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

Nic*_*ick 4 scala scala-2.8

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

m1=true
m2a=true
m2b=false
m3=true
Run Code Online (Sandbox Code Playgroud)

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));
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ith 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;
  }
Run Code Online (Sandbox Code Playgroud)

会给你你想要的结果.


Ran*_*ulz 5

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

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