【问题标题】:scala type matching for Tuple2Tuple2 的 scala 类型匹配
【发布时间】:2013-01-11 07:48:21
【问题描述】:

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

谁能给我一个快速的解释。 谢谢

【问题讨论】:

    标签: scala types match


    【解决方案1】:

    类型擦除。它无法在运行时告诉 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,由类型擦除提供。

    【讨论】:

    • 啊,谢谢!出于某种原因,eclipse 没有发出这个警告。我应该更了解并在 REPL 中尝试一下。谢谢!
    • 延迟接受...我想迟到总比没有好..对此感到抱歉
    【解决方案2】:
    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) 不起作用,即使它符合要求。

    【讨论】:

    • 嗯,很有趣。我想知道 @ 然后是否通过强制 scala 也匹配 y 来避免 adlbertc 提到的类型擦除。
    • y @ (y1: Boolean)可以写成y @ (_: Boolean)可以写成y: Boolean
    • 我想最接近 OP 代码的是case ti @ (_, _: Int) =&gt; ...
    【解决方案3】:

    您可以试试这个,只需对您的代码进行最少的更改即可正常工作。通过解包和输入,该功能可以正常工作。

    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")
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 2017-02-25
      • 2011-07-16
      • 2012-08-27
      • 1970-01-01
      相关资源
      最近更新 更多