问题描述
我刚开始学习 Scala 并找到了一段代码,这很好用,但我就是不明白为什么......
sealed abstract class Nat
case class Zero() extends Nat
case class Succ(n: Nat) extends Nat
def add(n: Nat,m: Nat): Nat = {
n match {
case Zero() => m
case Succ(prev) => add(prev,Succ(m))
}
}
Nat 和 Zero 的成员定义在一个额外的文件中(稍后使用),如下所示:
val zero = Zero()
val one = Succ(zero)
val two = Succ(one)
val three = Succ(Succ(one))
val four = Succ(Succ(two))
我现在的问题是:在第二种情况下,“prev”从未得到定义。这里会发生什么?背后的数学对我来说很清楚(比如 n+m == (n-1)+(m+1),重复直到 n==Zero())。到目前为止还好。但是定义的只是 Succ() 而不是一种 Prev()?
解决方法
在这种情况下,prev
在 case 语句中声明,这里:
case Succ(prev) => add(prev,Succ(m))
当您输入 case Succ(prev) ...
时,您正在使用模式匹配,并说:如果 n
是 Succ
类型,我们称其 n
参数为 prev
,然后返回 add(...)
所以基本上你将 Succ 类的 n 参数命名为 prev 以在箭头 =>
之后使用它
这个 Scala 功能甚至可以与正则表达式一起使用,您可以在其中捕获将放入您定义的变量中的组。
有关文档的更多信息:https://docs.scala-lang.org/tour/pattern-matching.html
,Scala 为您提供简洁的语法,因此您不必写出类似的东西
case Succ(prev) => add(prev,...)
我们可以通过考虑数据的结构来进行更高层次的推理并简单地编写
Private checkpopup As class_checkpopup
Public Sub checkbox_popup_fund(table)
Set checkpopup = New class_checkpopup
Let checkpopup.table = table
checkpopup.Show
Debug.Print checkpopup.table
End Sub
case class
es 在 scala 中自动定义一个名为 unapply
的方法。
正是这种 unapply
方法启用了这种模式匹配。
如果我使用名为 value
的成员定义一个 case 类,我可以通过使用 unapply 来获取它来提取该值:
case class Number( value: Int )
val valueOfNumber: Int = Number(5).value
println(valueOfNumber) // 5
// Using unapply
val testNumber: Number = Number(200)
val Number(numberValue) = testNumber
println(numberValue) // 200
执行 case Succ(prev) => add(prev,Succ(m))
时,您通过匹配 n
方法的类型签名将 Succ
的值 prev
提取为 unapply
。>
因此,定义了 prev
,它是匹配的 n
包含的值 Succ