gpt4 book ai didi

Scala:Function0 与按名称参数

转载 作者:行者123 更新时间:2023-12-02 04:21:54 24 4
gpt4 key购买 nike

任何人都可以给出关于名称参数 => TFunction0 参数 () => T 如何转换为的明确答案Scala 编译器相互之间?我知道它们并不相同,但区别非常微妙,因为它们在许多场景中可以互换使用。

示例:如果我定义

def someFunction: Int = 2
def f(x: => Int): Unit = println(x)

然后我就可以成功调用了

f(2)
f(someFunction)

() => Int 如何成为 => Int 的可接受替代品?

更一般地说,() => T 是普遍接受的名称 => T 参数的替代吗?

另外,如果我在以下推理上有误,请纠正我:=> T 永远不是 () => T 的可接受替代品,因为第一个是一个是值类型 (T),另一个是函数类型。也就是说,如果我有 def f(x: () => Int),我将永远无法传递 Int 或惰性 Int (无论如何都没有意义,因为没有惰性类型)。

最佳答案

好的,这是完整的分割。

def value: Int = ???
def method(): Int = ???

def f1(f: () => Int) = ???
def f2(f: => Int) = ???

f1(value) // fails
f1(method) // works
f2(value) // works
f2(method) // works with a warning "empty-paren method accessed as parameterless"
  1. f1(value)

此操作失败,因为 f1 需要一个 Unit => Int 函数,但给出了一个 Int 值。

  • f1(method)

  • 这个之所以有效,是因为 f1 需要一个函数,并且被赋予了一个方法。区别在于:method 不是 Scala 中的值;它是 Scala 中的值。它不能单独存在,而是它定义的上下文的一个属性(类、特征、对象等)。函数是一个值;它可以保存在一个集合中,作为另一个函数的参数,从函数返回等。当编译器需要一个函数并给定一个方法时,它会执行eta扩展。给定一个函数,例如f: (a: Int, b: Int) => Int,eta扩展是在保留签名的同时在其周围创建另一层的过程,因此它变成 (a: Int, b: Int) => f(a, b)。这种技术很有用,因为我们可以将方法转化为函数。给定一些方法 def f(a: Int): Int = ???,我们可以执行 eta 扩展来创建一个 Int => Int 类型的函数: (a: Int) => f(a)。我写了一个blog post如果您有兴趣的话,前一段时间就已经讨论过了。

  • f2(value)

  • 工作正常,但请注意每次在函数体中使用传递的值时都会访问它。

  • f2(method)

  • 可以工作,但有一个警告,表明我们正在通过不使用括号来调用使用空括号定义的方法。好的做法是,当它们仅表示一个值时,使用不带括号的方法(例如 f),但每次访问时都会重新计算该值,例如numberOfUpvotes,并在执行某种副作用时使用带空括号的方法(例如 f()),因此该方法不是幂等的,例如createSnapshot()(同样,这不应该出现在纯函数代码中)。

    忠告:不要用什么来代替什么来阻碍你的思想。不要使用替代品。如果某物需要一个功能,就为它提供一个功能。如果需要一个值,请提供一个值。如果定义的方法不带括号,则调用不带括号的方法。如果它有括号,则用括号调用它。

    如果您需要从方法转到函数并且编译器需要一个函数,则 eta 扩展将自动发生。如果它不需要函数,您需要手动执行。

    def f(): Int = ???
    val a = f // no function context; a is a string
    val b: () => Int = f // b is a function Unit => Int
    val c = f2 _ // c is a function Unit => Int

    最后一种情况是部分应用的函数。我觉得我现在讲得太宽泛了,所以我就到这里为止。我希望这有帮助。

    关于Scala:Function0 与按名称参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46185458/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com