【问题标题】:scala accessing a list object inside another listscala访问另一个列表中的列表对象
【发布时间】:2013-08-02 23:07:08
【问题描述】:

我正在尝试访问具有特定类型的另一个列表中的列表对象

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
  • @theone 你是什么意思?
  • 我正在回复一条似乎已被删除的评论。无论如何,我已经发布了一个详细说明HList 的答案:)

标签: scala collections


【解决方案1】:

所以xList[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")) 有效

【讨论】:

  • 模式匹配是一种更安全但更详细的方法。见stackoverflow.com/questions/171489/…
  • 模式匹配,在这种情况下,打开“下一个蠕虫罐”:匹配(2.10.2)允许我匹配List[_],但类型擦除阻止(强类型)匹配给List[String];编译会发出警告。
【解决方案2】:

Scala 编译器会简单地说你在列表 x 中有对象(或者可能是任何对象)。这就是为什么。您必须将第三个元素转换为 List 才能分配给 List 变量。

【讨论】:

    【解决方案3】:

    问题是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)
    

    更多关于它herehere

    【讨论】:

      【解决方案4】:

      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] 只能容纳 Strings。如果将混合类型的元素放入List,那么List 的参数化类型将成为所有元素共有的最具体的类型。

      StringList 最常用的特定类型是Any。所以在这个例子中,x 的类型是 List[Any]

      val x = List("item1" , "item2" , List ("a,b,c"))
      

      HList可以容纳不同类型的元素,并维护每个元素的类型。

      【讨论】:

      • 这个例子产生了一个错误。此行的多个标记(在方法应用中)(在方法应用中)(在方法应用中)(在方法应用中)])at.Out 不能应用于(Int) - 找到隐式转换:x => hlistOps(x)
      • 已修复。在 Scala 控制台中测试。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 2016-11-18
      • 2017-01-10
      相关资源
      最近更新 更多