Scala 按名称参数的使用 [英] Use of Scala by-name parameters

查看:41
本文介绍了Scala 按名称参数的使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读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 案例类的构造函数.用于传递 headtail 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)

据我了解所使用的语法,它强制创建两个只返回 headtail val 的 Function0 对象.这与仅传递 headtail(没有 () => 前缀)有何不同,因为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆