scala函数参数的情况是否相关?

时间:2010-06-24 03:33:35

标签: scala scala-2.8

关于以下scala代码,函数m2a和m2b明显不同于参数的情况,即abc vs Abc。这似乎在结果上有所不同,如下面的例子所示。当使用最近的2.8编译器运行它时,会产生以下结果(我希望所有这些都是真的)。任何见解都将不胜感激。

m1=true
m2a=true
m2b=false
m3=true

package sample

import scala.xml._

object ParamTest extends Application {

  def m1(n:Node, abc:String):Boolean = {
    n == <id>{Text(abc)}</id>
  }

  def m2a(n:Node, Abc:String):Boolean = n match {
    case <id>{Text(Abc)}</id> => true
    case _ => false;
  }

  // why does this one not work?
  def m2b(n:Node, abc:String):Boolean = n match {
    case <id>{Text(abc)}</id> => true
    case _ => false;
  }

  def m3(n:Node, abc:String):Boolean = n match {
    case Elem(_,"id",_,_, c @_ *) => {
      c contains Text(abc)
    }
  }

  def runner(n:Node, f:(Node, String)=>Boolean):Boolean = {
    f(n, "x") && !f(n, "y") && !f(n, "");
  }

  val x = <id>x</id>

  println("m1="+runner(x, m1));
  println("m2a="+runner(x, m2a));
  println("m2b="+runner(x, m2b));
  println("m3="+runner(x, m3));
}

2 个答案:

答案 0 :(得分:5)

这里的技巧是Scala如何处理case表达式中的变量。编译器采用case表达式中的小写变量来引入新变量,然后对其进行模式匹配。因此,在方法m2b中,方法参数“abc”实际上是未使用的。 case表达式变量“abc”将匹配任何字符串,因为它不受其他约束。因此,在m2b的第一种情况下,“y”成功匹配。 case表达式中的大写变量不会引入新变量,因此在m2a中匹配的行为与预期的一致。

匹配小写变量值的最简单方法是将其包装在反引号中。因此

def m2b(n:Node, abc:String):Boolean = n match {
    case <id>{Text(`abc`)}</id> => true
    case _ => false;
  }

会为您提供您期望的结果。

答案 1 :(得分:5)

在模式匹配中,模式中以小写字母开头的标识符被视为可以绑定到匹配目标中的值的自由模式变量。那些以大写字母开头的是所谓的稳定标识符,并且必须已经绑定在匹配表达式的上下文中,并且该绑定的值必须等于匹配目标的子表达式与该稳定标识符在模式表达式中的位置对应的值。

此外,在此特定示例中相关,模式变量(小写名称)将 shadow 在匹配表达式的上下文中生效的任何现有的同名绑定(包括提供匹配目标值的表达式。)