在 Scala 中创建和传递包含多种类型的字典的最佳方法是什么? [英] What is the best way to create and pass around dictionaries containing multiple types in scala?

查看:30
本文介绍了在 Scala 中创建和传递包含多种类型的字典的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我所说的字典是指从名称到可用作方法返回值的值的轻量级映射.

By dictionary I mean a lightweight map from names to values that can be used as the return value of a method.

我所知道的选项包括创建 case 类、创建 anon 对象以及从 Strings -> Any 制作映射.

Options that I'm aware of include making case classes, creating anon objects, and making maps from Strings -> Any.

  • Case 类需要脑力开销来创建(名称),但是是强类型的.
  • 匿名对象似乎没有很好的文档记录,我不清楚如何将它们用作参数,因为没有命名类型.
  • 来自字符串的映射 -> 任何需要转换才能检索.

还有什么更好的吗?

理想情况下,这些可以从 json 构建并在适当的时候转换回它.

Ideally these could be built from json and transformed back into it when appropriate.

我不需要静态类型(虽然它会很好,但我知道这是不可能的) - 但我确实想避免显式转换.

I don't need static typing (though it would be nice, I can see how it would be impossible) - but I do want to avoid explicit casting.

推荐答案

这是你想要的根本问题:

Here's the fundamental problem with what you want:

def get(key: String): Option[T] = ...

val r = map.get("key")

r 的类型将根据 get 的返回类型定义——那么,该类型应该是什么?从哪里可以定义?如果将其设为类型参数,则相对容易:

The type of r will be defined from the return type of get -- so, what should that type be? From where could it be defined? If you make it a type parameter, then it's relatively easy:

import scala.collection.mutable.{Map => MMap}
val map: MMap[String, (Manifest[_], Any) = MMap.empty
def get[T : Manifest](key: String): Option[T] = map.get(key).filter(_._1 <:< manifest[T]).map(_._2.asInstanceOf[T])
def put[T : Manifest](key: String, obj: T) = map(key) = manifest[T] -> obj

示例:

scala> put("abc", 2)

scala> put("def", true)

scala> get[Boolean]("abc")
res2: Option[Boolean] = None

scala> get[Int]("abc")
res3: Option[Int] = Some(2)

当然,问题在于您必须告诉编译器您希望在该键下的映射上存储什么类型.不幸的是,根本没有办法解决这个问题:编译器无法知道在编译时将在该键下存储什么类型.

The problem, of course, is that you have to tell the compiler what type you expect to be stored on the map under that key. Unfortunately, there is simply no way around that: the compiler cannot know what type will be stored under that key at compile time.

您采用的任何解决方案最终都会遇到同样的问题:不知何故,您必须告诉编译器应该返回什么类型.

Any solution you take you'll end up with this same problem: somehow or other, you'll have to tell the compiler what type should be returned.

现在,这不应该成为 Scala 程序的负担.以上面的 r 为例……然后您将使用该 r 做某事,对吗?你使用它的东西会有适合某种类型的方法,既然你知道方法是什么,那么你也必须知道 r 的类型必须是什么.

Now, this shouldn't be a burden in a Scala program. Take that r above... you'll then use that r for something, right? That something you are using it for will have methods appropriate to some type, and since you know what the methods are, then you must also know what the type of r must be.

如果不是这种情况,那么代码存在根本性的错误——或者,也许您还没有从想要地图到知道您将用它做什么.

If this isn't the case, then there's something fundamentally wrong with the code -- or, perhaps, you haven't progressed from wanting the map to knowing what you'll do with it.

这篇关于在 Scala 中创建和传递包含多种类型的字典的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆