我正在编写一种规则引擎,它遍历树并为每个子树建立上下文,然后使用匹配条件来验证树并推断有关节点的信息。
我希望我可以使用嵌套的匹配条件(在case类构造函数上),并通过使用相同的构造函数属性名称来匹配外部和内部属性,如下所示:
val context = Foo(42, "Hello, World")
val items = List(
Foo(42, "Hello, World"),
Foo(42, "Bar"),
Foo(24, "Hello, World"),
Foo(2, "Goodbye")
)
def matchFoo(context: Foo, item: Foo): String = {
context match {
case Foo(num, text) =>
item match {
case Foo(num, text) => "Exact match"
case Foo(otherNum, text) => "Text match"
case Foo(num, otherText) => "Number match"
case Foo(otherNum, otherText) => "No match"
}
}
}
items.map(i => matchFoo(context, i))
但我只得到了4个“完全匹配”的结果。我猜测case Foo(num,text)的内部匹配隐藏了外部num,text变量,因此匹配任何Foo项。
我可以通过使用显式的保护条件来解决这个问题,但这是我试图避免的:
val context = Foo(42, "Hello, World")
val items = List(
Foo(42, "Hello, World"),
Foo(42, "Bar"),
Foo(24, "Hello, World"),
Foo(2, "Goodbye")
)
def matchFoo(context: Foo, item: Foo): String = {
context match {
case Foo(num, text) =>
item match {
case Foo(otherNum, otherText) if otherNum == num && otherText == text => "Exact match"
case Foo(otherNum, _) if otherNum == num => "Number match"
case Foo(_, otherText) if otherText == text => "Text match"
case _ => "No match"
}
}
}
items.map(i => matchFoo(context, i))
有没有办法做到这一点,或者是警卫条件的方式去?
1条答案
按热度按时间f45qwnt81#
您是正确的,内部模式中的
num
和text
创建了隐藏外部变量的新变量绑定,而不是使用外部变量的值作为匹配值。你可以用反引号(`)来引用这些名称,以获得你想要的行为:输出量:
这种语法在Scala语言规范中关于模式匹配的章节中的“稳定标识符模式”一节中进行了描述:
稳定标识符模式是稳定标识符r。r 的类型必须符合模式的预期类型。该模式匹配任何值 v,使得 r == v(参见此处)。
为了解决与变量模式的语法重叠,稳定的标识符模式可能不是以小写字母开头的简单名称。但是,可以将这样的变量名括在反引号中;则将其视为稳定标识符模式。
例如,考虑以下类定义:
这里,前三个模式是稳定的标识符模式,而最后一个是可变的模式。