1

我正在做一些练习,并注意到以下匹配 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。我认为这里正在进行一些类型转换,但我不清楚为什么。

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

4

3 回答 3

4

类型擦除。它无法判断Tuple运行时内部的类型。它会编译得很好,但它应该发出警告。这就是我:paste在 REPL 模式下执行此操作时发生的情况:

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,由类型擦除提供。

于 2013-01-28T01:49:00.820 回答
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")
}
于 2013-01-28T06:10:27.037 回答
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) 不起作用,即使它符合要求。

于 2013-01-28T04:35:00.507 回答