我正在进行一些练习并注意到以下与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。我假设这里有一些类型的铸造,但我不明白为什么。
有人可以给我一个快速解释。 感谢
答案 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")
}