开发者

Why does my pattern match on a collection fail in Scala?

My code is as follows

  val hash = new HashMap[String, List[Any]]
  hash.put("test", List(1, true, 3))
  val result = hash.get("test")
  result match {
    case List(Int, Boolean, Int) => println("found")
    case _ => println("not found")
  }

I would expect "found" to be printed but "not found" is printed. I'm trying to match开发者_如何转开发 on any List that has three elements of type Int, Boolean, Int


You are checking for a list containing the companion objects Int and Boolean. These are not the same as the classes Int and Boolean.

Use a Typed Pattern instead.

val result: Option[List[Any]] = ...
result match {
  case Some(List(_: Int, _: Boolean, _: Int)) => println("found")
  case _                                      => println("not found")
}

Scala Reference, Section 8.1 describes the different patterns you can use.


The first problem is that the get method returns an Option:

scala>   val result = hash.get("test")
result: Option[List[Any]] = Some(List(1, true, 3))

So you'd need to match against Some(List(...)), not List(...).

Next, you are checking if the list contains the objects Int, Boolean and Int again, not if it contains objects whose types are Int, Boolean and Int again.

Int and Boolean are both types and object companions. Consider:

scala> val x: Int = 5
x: Int = 5

scala> val x = Int
x: Int.type = object scala.Int

scala> val x: Int = Int
<console>:13: error: type mismatch;
 found   : Int.type (with underlying type object Int)
 required: Int
       val x: Int = Int
                    ^

So the correct match statement would be:

case Some(List(_: Int, _: Boolean, _: Int)) => println("found")


The following also works for Scala 2.8

List(1, true, 3) match {
  case List(a:Int, b:Boolean, c:Int) => println("found")
  case _ => println("not found")
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜