Scala 按名称参数的使用 [英] Use of Scala by-name parameters
问题描述
我正在阅读Scala 中的函数式编程"这本书,并且遇到了一个例子我不完全明白.
I am going through the book "Functional Programming in Scala" and have run across an example that I don't fully understand.
在关于严格/懒惰的章节中,作者描述了 Streams 的构造并有这样的代码:
In the chapter on strictness/laziness the authors describe the construction of Streams and have code like this:
sealed trait Stream[+A]
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream {
def cons[A](hd: => A, tl: => Stream[A]) : Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head, () => tail)
}
...
}
我的问题是在智能构造函数 (cons
) 中,它调用 Cons
案例类的构造函数.用于传递 head
和 tail
vals 的特定语法对我来说没有意义.为什么不像这样调用构造函数:
The question I have is in the smart constructor (cons
) where it calls the constructor for the Cons
case class. The specific syntax being used to pass the head
and tail
vals doesn't make sense to me. Why not just call the constructor like this:
Cons(head, tail)
据我了解所使用的语法,它强制创建两个只返回 head
和 tail
val 的 Function0 对象.这与仅传递 head
和 tail
(没有 () =>
前缀)有何不同,因为 Cons
case 类已经定义为按名称获取这些参数?这不是多余的吗?还是我错过了什么?
As I understand the syntax used it is forcing the creation of two Function0 objects that simply return the head
and tail
vals. How is that different from just passing head
and tail
(without the () =>
prefix) since the Cons
case class is already defined to take these parameters by-name anyway? Isn't this redundant? Or have I missed something?
推荐答案
区别在于 =>A
不等于 () =>A
.
The difference is in => A
not being equal to () => A
.
前者是按名称传递,后者是一个不带参数返回一个A的函数.
The former is pass by name, and the latter is a function that takes no parameters and returns an A.
您可以在 Scala REPL 中对此进行测试.
You can test this out in the Scala REPL.
scala> def test(x: => Int): () => Int = x
<console>:9: error: type mismatch;
found : Int
required: () => Int
def test(x: => Int): () => Int = x
^
在我的示例中简单地引用 x
会导致调用参数.在您的示例中,它正在构建一个延迟调用 x 的方法.
Simply referencing x
in my sample causes the parameter to be invoked. In your sample, it's constructing a method which defers invocation of x.
这篇关于Scala 按名称参数的使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!