【问题标题】:Scala : Pattern matching against generic list typesScala:针对通用列表类型的模式匹配
【发布时间】:2014-09-26 11:13:28
【问题描述】:

我试图根据列表的内部元素,特别是它们的类型,将列表与某些操作相匹配:

def car1 = new Car[Racing] {}
def car2 = new Car[Pickup] {}

var myCars = List(car1,car2)

myCars match {

     case Racing :: Pickup => print("your first car is awesome but not your 2nd!"

}

显然,上面的案例是尝试使用伪代码来描述我正在尝试做的事情,但是,它失败了。

在 scala 中匹配集合中存在的值类型的惯用方法是什么?

【问题讨论】:

    标签: scala collections types


    【解决方案1】:

    我将创建第三个类(我们称之为 CarModel),Racing 和 Pickup 都从该类扩展,然后以下代码将起作用:

    def traverseList(list: List[CarModel]): Unit = list match {
      case (raceCar: Racing) :: rest => {
        print("your first car is awesome but not your 2nd!")
        traverseList(rest)
      }
      case (pickUpCar: PickUp) :: rest => {
        doSomethingElse()
        traverseList(rest)
      }
      case Nil => 
    }
    

    以上是检查列表中每种类型的递归示例,但如果您想检查列表中的第一个元素,可以简单地使用列表的 match 语句。

    如果您想检查列表的类型,正如@Naetmul 提到的,您将遇到type erasure。如果您想验证列表的类型,post 说明了克服它的方法。

    如果您有任何问题,请告诉我!

    【讨论】:

    • 第二个例子不是遭受了类型擦除吗?
    • 哇!我刚刚阅读了类型擦除,它让我大吃一惊。这绝对是一个我不知道的很酷的概念。谢谢你的精彩课程,你是绝对正确的,它会受到类型擦除的影响。我猜想使用 Manifest 或 ClassTag 的两种解决方法如下所述:stackoverflow.com/questions/1094173/…
    【解决方案2】:

    如果您只有 2 个元素,不确定为什么要使用列表 - 建议使用元组。无论如何,我会这样做:

    myCars match {
      case List((_: Racing), (_: Pickup)) => 
        print("your first car is awesome but not your 2nd!"
    }
    

    请注意,您没有在打印声明中使用这些汽车,因此我没有标记它们 - 而是将它们保留为 _

    【讨论】:

    • 这看起来有效,但我得到: scala.MatchError: List(app.MyClass$$anon$3@2ed053a, app.MyClass$$anon$4@16f22456, app.MyClass$$anon$5@ 732f95de) (类 scala.collection.immutable.$colon$colon)
    • 看起来你传入了一个包含 3 个元素的列表。
    • 谢谢。所以,我想这现在是一个子问题:stackoverflow.com/questions/25166310
    猜你喜欢
    • 1970-01-01
    • 2011-11-27
    • 2020-08-09
    • 2016-03-10
    • 2013-03-17
    • 2014-03-05
    • 2013-09-06
    • 1970-01-01
    相关资源
    最近更新 更多