我正在尝试访问具有特定类型的另一个列表中的列表对象
val x = List ("item1" , "item2" , List ("a","b","c"))
val list_from_x :List [String]= x(2) // producing error
我需要我list_from_x的类型List [String]
知道如何进行这种转换?
我正在尝试访问具有特定类型的另一个列表中的列表对象
val x = List ("item1" , "item2" , List ("a","b","c"))
val list_from_x :List [String]= x(2) // producing error
我需要我list_from_x的类型List [String]
知道如何进行这种转换?
HList救援:
import shapeless._
import Nat._
val x = "item1" :: "item2" :: List("a,b,c") :: HNil
val list_from_x = x(_2)
list_from_x有类型List[String]
有关更多信息,请参阅无形github 页面。
正如其他答案所提到的, aList只能容纳某种类型的元素。例如,aList[String]只能容纳Strings。如果将混合类型的元素放入 aList中,则参数化的类型List将成为所有元素共有的最具体的类型。
String和最常见的特定类型List是Any。所以在这个例子中,x是类型List[Any]:
val x = List("item1" , "item2" , List ("a,b,c"))
HList可以容纳不同类型的元素并维护每个元素的类型。
x**类型也是如此List[Object],因为您使用了两个不同(否则不相关)的类作为该列表的元素。如果没有类型转换,您将无法访问类型以外的元素Any:
val listFromX = x(2).asInstanceOf[List[String]]
这不是类型安全的,因此您需要检查元素类型 ( x(2).isInstanceOf[List[_]]) 或模式匹配。
** 使用 REPL 来验证这一点;虽然val x: List[Any] = List ("item1" , "item2" , List ("a,b,c"))有效
Scala 编译器只会说你在列表 x 中有对象(或者可能是任何对象)。这就是为什么。您必须将第三个元素转换为 List 才能分配给 List 变量。
该问题被List定义为List[+A](来源)。这意味着List采用协变类型的类型参数。(您可以将协方差视为从窄到宽的类型转换。例如:如果DogextendsAnimal并且如果您这样做Animal a = new Dog(),您有一个 Dog(窄)转换为 Animal(宽))
x是类型List[Object]。正在做
scala> val x = List ("item1" , "item2" , List ("a,b,c"))
x: List[Object] = List(item1, item2, List(a,b,c))
val list_from_x :List [String]= x(2)
最终从List[Object](广义)转变为List[String](狭义)。这是相反的。因此编译器抛出错误,因为 List 是协变的。
例如:以下是完全有效的。由于协方差:
scala> val x = List("hello")
x: List[String] = List(sdf)
scala> val o:List[Object] = x
o: List[Object] = List(sdf)