我正在尝试使用特定类型
访问另一个列表中的列表对象val x = List ("item1" , "item2" , List ("a","b","c"))
val list_from_x :List [String]= x(2) // producing error
我需要list_from_x
类型为List [String]
我知道如何进行这样的转换吗?
答案 0 :(得分:2)
所以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"))
有效
答案 1 :(得分:2)
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 page。
正如其他答案所提到的,List
只能保存某种类型的元素。例如,List[String]
只能保留String
个。如果将混合类型的元素放入List
,那么List
的参数化类型将成为所有元素共有的最具体类型。
String
和List
的最常见类型是Any
。因此,在此示例中,x
的类型为List[Any]
:
val x = List("item1" , "item2" , List ("a,b,c"))
HList
可以包含不同类型的元素并维护每个元素的类型。
答案 2 :(得分:0)
Scala编译器只会说你在列表x中有对象(或者可能是Any)。这就是为什么。您必须将第3个元素转换为List才能分配给List变量。
答案 3 :(得分:0)
问题是List
定义为List[+A]
(source)。这意味着List
采用共变型的类型参数。 (您可以将协方差视为从窄到宽的类型转换。例如:如果Dog
延伸Animal
,如果您执行Animal a = new Dog()
,则您有一个狗(缩小)转换为动物(更广泛))
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)