I am trying to access a list object inside of another list with a specific type
val x = List ("item1" , "item2" , List ("a","b","c"))
val list_from_x :List [String]= x(2) // producing error
I need my list_from_x
of type to be of List [String]
any idea how to I do such conversion ?
So x
is of type List[Object]
**, because you've used two different (otherwise unrelated) classes as elements of that list. You'll be unable to access elements other than of type Any
without a type cast:
val listFromX = x(2).asInstanceOf[List[String]]
This is not type-safe, so you'll want to check element types ( x(2).isInstanceOf[List[_]]
) or pattern matching.
** Use the REPL to verify this; though val x: List[Any] = List ("item1" , "item2" , List ("a,b,c"))
works
HList
to the rescue:
import shapeless._
import Nat._
val x = "item1" :: "item2" :: List("a,b,c") :: HNil
val list_from_x = x(_2)
list_from_x
has the type List[String]
See the shapeless github page for more info.
As other answers have mentioned, a List
can only hold elements of a certain type. For example, a List[String]
can only hold String
s. If you put elements of mixed types into a List
, then the parametrised type of the List
will become the most specific type common to all the elements.
The most specific type common to String
and List
is Any
. So in this example, x
is of type List[Any]
:
val x = List("item1" , "item2" , List ("a,b,c"))
HList
can hold elements of different types and maintain each element's type.
Scala compiler will simply say you got Objects (or may be Any) inside list x. That's why. You have to cast the 3rd element into a List in order to assign into a List variable.
The issue is List
is defined as List[+A]
( source ). Which means List
takes a type parameter of co-variant type. (You can think of co-variance as type converting from narrow to broader. For ex: if Dog
extends Animal
and if you do Animal a = new Dog()
, you have a Dog (narrow) converting to Animal (broader))
x
is of type List[Object]
. Doing
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)
is ultimately converting from List[Object]
(broader) to List[String]
(narrow). Which is contra-variant. Hence the compiler threw error because List is meant to be co-variant.
For ex: the below is completely valid. Thanks to co-variance:
scala> val x = List("hello")
x: List[String] = List(sdf)
scala> val o:List[Object] = x
o: List[Object] = List(sdf)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.