【问题标题】:Pattern Matching a List[_] in Scala在 Scala 中匹配列表 [_] 的模式
【发布时间】:2017-10-14 12:05:21
【问题描述】:

我有以下代码

def function1(obj:Any)={

obj match {


        case l:List[Map[String,Any]]=> {
          println("ListMap" + l.toString())
        }
        case l:List[String]=> {
          println ("list String" + l)
        }
        case None =>
      }
}

当我将地图列表和字符串传递给此函数时,它只会打印第一个 case 语句,而不会打印第二个。有什么我做错了吗?

【问题讨论】:

  • 为什么会转到第二个?这是使用Any btw 的可怕代码,使用这样的类型系统毫无意义。 case 语句的重点是每个 case 评估一次,以匹配给定的条件。
  • 你应该会得到一个关于类型擦除的警告——第二种情况永远不会匹配。一般来说,您不能依赖于通过x : A[Type] 对模式中的泛型代码进行类型检查,而只能依赖于真正的类型匹配器(即具有 unapply 方法的对象)。
  • 我必须使用 Any 因为我的数据是这样的......我别无选择
  • 您也可以将函数设为通用:def f[T](obj : T) = obj match { case Nil => ... ; case x::xs => ...。如果你需要处理obj,你可以传递一个T => ResultType类型的附加参数。
  • 这是不可能的,因为类型擦除 (docs.oracle.com/javase/tutorial/java/generics/erasure.html)。无法在运行时检测泛型类型的类型参数。

标签: scala pattern-matching type-erasure


【解决方案1】:

下面的草图怎么样(类型取决于你的使用):

def f[T](obj : List[T], trans : T => String) = obj.map(trans).mkString

然后你拨打f如下:

scala> f[Map[Int,Int]](List(Map(1->2, 3->4), Map(0->0)), _.toList.map( x => (x._1 - x._2).toString).mkString(","))
res5: String = -1,-10

scala> f[String](List("abc","def","ghi"), x => x.reverse)
res6: String = cbafedihg

【讨论】:

    【解决方案2】:

    原因是它们都是List(该函数只是检查outerdataType而忽略inner dataType
    您可以根据自己的情况使用以下解决方案并根据需要进行修改。

     def function(obj: Any) : Unit = {
       Try {
         obj.asInstanceOf[List[Map[String, Any]]].map(function2(_))
         println("ListMap")
       }getOrElse (
         Try{
            obj.asInstanceOf[List[String]].map(function2(_))
            println("List of String")
         }getOrElse
           println("do nothing")
         )
     }
    

    之所以需要function2,是因为没有transformation,就无法识别casted datatype。无论如何,您在传递给function 的数据中都需要一些transformation

     def function2(obj: Any) = obj match {
       case _ : Map[String, Any] => //do what you want with your map
       case _ : String => //do what you want with your string list
       case _  => // this is not done for now
     }
    

    我希望这正是你要找的东西

    【讨论】:

    • 这是有道理的,但我们不应该检查失败,因为您将它包装在 Try {}
    • 失败被gerOrElse捕获,所以我们不需要显式检查Failure
    猜你喜欢
    • 2018-10-01
    • 2012-10-14
    • 2015-05-30
    • 2015-07-29
    • 2015-01-17
    • 1970-01-01
    • 2015-07-27
    • 2023-03-06
    • 2015-04-27
    相关资源
    最近更新 更多