Tuple2的scala类型匹配

时间:2013-01-28 01:07:36

标签: scala types match

我正在进行一些练习并注意到以下与tuple2匹配的行为。这有什么特别的原因吗?

 def test(x: Any): Unit= x match{
  case i: Int => println("int")
  case b: Boolean => println("bool")
  case ti: (_, Int) => println("tuple2 with int")
  case tb: (_, Boolean)=> println("tuple2 with boolean")
  case _ => println("other")
  }                                                

test(false) //prints bool
test(3) ///prints int
test((1,3)) //prints tuple with int
test((1,true)) //prints tuple with int 

如果我交换ti和tb个案,那么(1,3)用布尔值打印tuple2。我假设这里有一些类型的铸造,但我不明白为什么。

有人可以给我一个快速解释。 感谢

3 个答案:

答案 0 :(得分:4)

键入擦除。它无法在运行时告诉Tuple内的类型。它会编译正常,但它应该发出警告。当我在REPL中以:paste模式执行此操作时会发生这种情况:

scala> :paste
// Entering paste mode (ctrl-D to finish)

def test(x: Any): Unit= x match{
  case i: Int => println("int")
  case b: Boolean => println("bool")
  case ti: (_, Int) => println("tuple2 with int")
  case tb: (_, Boolean)=> println("tuple2 with boolean")
  case _ => println("other")
  }                                                

// Exiting paste mode, now interpreting.

<console>:10: warning: non-variable type argument Int in type pattern (_, Int) is unchecked since it is eliminated by erasure
         case ti: (_, Int) => println("tuple2 with int")
                  ^
<console>:11: warning: non-variable type argument Boolean in type pattern (_, Boolean) is unchecked since it is eliminated by erasure
         case tb: (_, Boolean)=> println("tuple2 with boolean")
                  ^
<console>:11: warning: unreachable code
         case tb: (_, Boolean)=> println("tuple2 with boolean")
                                        ^
test: (x: Any)Unit

请注意上次警告,它表示(_, Boolean)无法访问,因为(_, Int)将在每个Tuple2上匹配,提供类型擦除。

答案 1 :(得分:0)

def test(x: Any) {
x match {
  case xi: Int => println("int [" + xi + "]")
  case yb: Boolean => println("boolean [" + yb + "]")
  case (x, y @ (y1: Int)) => println("[" + x + ", int(" + y + ")]")
  case (x, y @ (y1: Boolean)) => println("[" + x + ", boolean(" + y + ")]")
  case _ => println("anything else")
}

}

test(1);
test(true);
test("hello", 1);
test("hello", false);
它似乎以这种方式工作。 然而,只是case(x,y @ Int)不起作用,甚至认为它符合。

答案 2 :(得分:0)

您可以试试这个,只需对代码进行最少的更改即可。通过解压缩和打字,该功能正常。

def test: Any => Unit = _ match{
  case i: Int => println("int")
  case b: Boolean => println("bool")
  case (x:Any, y: Boolean)=> println("tuple2 with boolean")
  case (x:Any, y: Int) => println("tuple2 with int")
  case _ => println("other")
}