我遇到了这个 scala 代码,我试图弄清楚它在做什么,除了它返回一个 int 的事实。我不确定这三行:
l match {
case h :: t =>
case _ => 0
功能 :
def iterate(l: List[Int]): Int =
l match {
case h :: t =>
if (h > n) 0
case _ => 0
}
我遇到了这个 scala 代码,我试图弄清楚它在做什么,除了它返回一个 int 的事实。我不确定这三行:
l match {
case h :: t =>
case _ => 0
功能 :
def iterate(l: List[Int]): Int =
l match {
case h :: t =>
if (h > n) 0
case _ => 0
}
首先,您定义了一个名为的函数iterate,并将返回类型指定为Int. 它有 arity 1,l类型参数List[Int]。
该List类型在整个函数式编程中都很突出,它的主要特征是它具有高效的前置,并且很容易将任何内容分解List为头部和尾部。头部将是列表的第一个元素(如果非空),尾部将是其余的List(本身是 a List) - 这对于在 上运行的递归函数非常有用List。
这match被称为模式匹配。它本质上是switchC 语言中的一个语句,但功能更强大 - 将switch您限制为常量(至少在 C 中是这样),但match.
现在,您case拥有的第一个h :: t-::被称为“缺点”,这是函数式编程的另一个术语。List当您通过前置从另一个创建新的时List,您可以使用::运算符来执行此操作。
例子:
val oldList = List(1, 2, 3)
val newList = 0 :: oldList // newList == List(0, 1, 2, 3)
在 Scala 中,以 a 结尾的运算符:实际上是右手边的方法,因此0 :: oldList相当于oldList.::(0)- 0 :: oldListis 语法糖,使其更易于阅读。
我们可以定义oldList为
val oldList = 1 :: 2 :: 3 :: Nil
whereNil代表一个空的List。将其分解为以下步骤:
3 :: Nil首先求值,创建List(3)具有头部 3 和空尾部的 a 的等价物。List(3)。List(2, 3)。List的结果List(1, 2, 3)分配给val oldList.
现在,当您使用::模式匹配时,您实际上将 a 分解List为头部和尾部,就像我们创建List上面的方式相反。当你这样做时
l match {
case h :: t => ...
}
你是说如果可能的话分解l成一个头和一个尾巴。如果你成功分解,你可以使用这些h和t变量来做任何你想做的事情。通常你会做一些类似h的事情,然后调用递归函数 on t。
这里要注意的一件事是你的代码不会编译..你做了一个if (h > n) 0但没有明确else的所以发生的事情是你的代码对编译器看起来像这样:
if (h > n) 0
else { }
它有类型AnyVal(常见的超类型0和“无”),违反了你的Int保证 - 你将不得不添加一个else带有一些失败值或其他东西的分支。
第二个case _ =>就像default中的 a ,它捕获第一个中switch的头/尾分解失败的任何内容case。
您的代码基本上是这样做的:
l List参数,看看能不能分解成头尾。n. 如果大于n,则函数返回 0。(如果不大于,则需要添加发生的情况)这称为模式匹配。这就像一个switch声明,但更强大。
一些有用的资源:
http://www.scala-lang.org/node/120
http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-4