【发布时间】:2011-07-04 05:53:05
【问题描述】:
是否可以根据 Scala 中的另一个清单定义清单?
我几乎让自己相信这是不可能的,因为 Scala Manifest 信息不打算动态使用。
这就是问题所在。我有一个函数可以返回多种类型的对象(String、Int、List[Int]、List[List[String]] 等)。为了支持这些多种类型,返回类型设置为 Any,但由于类型擦除有关列表、地图等中支持的类型的信息会丢失。为了恢复一些细节,我返回了一个 Manifest 以及返回类型。
但是,返回的信息可能会被放置在另一个列表或映射中,然后从另一个函数返回。我想更新清单以包含该类型现在是清单定义的先前类型的 List 或 Map 的事实。
这是一些示例代码
def returnWithManifest[T: Manifest](x: T) = (x, manifest[T])
// May return String, Int, List[Int], List[List[String]], ...
def contrivedExample(t: String): (Any, Manifest[_]) = t match {
case "String" => returnWithManifest("test")
case "Int" => returnWithManifest(1)
case "Boolean" => returnWithManifest(true)
case "List[Int]" => returnWithManifest(List(1,2,3))
case "List[List[String]]" =>
returnWithManifest(List(List("a","b"),List("c","d")))
case _ => returnWithManifest(None)
}
scala> val v1 = contrivedExample("List[Int]")
v1: (Any, Manifest[_]) = (List(1, 2, 3),scala.collection.immutable.List[Int])
scala> val x = v1._1
x: Any = List(1, 2, 3)
scala> val m = v1._2
m: scala.reflect.Manifest[_] = scala.collection.immutable.List[Int]
scala> val v2 = List(x)
v2: List[Any] = List(List(1, 2, 3))
从“v1”的清单中,我知道 v1 的类型为 List[Int],所以当我创建“v2”时,我应该拥有创建清单所需的所有信息,以识别类型为 List[List[Int] ]],但我只有 List[Any] 可以使用。也许语法如下:
val v2: m = List(x)
val v2 = List[m](x)
我意识到我似乎在尝试动态定义一个类型,但实际上这些信息是与静态已知类型的类型擦除相关的元数据。我想如果这可以解决,那么类型擦除就可以解决。但是,至少我认为我应该能够做类似的事情:
scala> val m2 = m.wrapInList()
m2: scala.reflect.Manifest[_] =
scala.collection.immutable.List[scala.collection.immutable.List[Int]]
【问题讨论】:
-
我真的很想知道是什么限制促使你使用这种奇怪的设计?