我正在尝试访问具有特定类型的另一个列表中的列表对象
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]
只能容纳String
s。如果将混合类型的元素放入 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
采用协变类型的类型参数。(您可以将协方差视为从窄到宽的类型转换。例如:如果Dog
extendsAnimal
并且如果您这样做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)