gpt4 book ai didi

scala - 关于按名称调用和 0-arity 函数之间区别的一些问题

转载 作者:行者123 更新时间:2023-12-04 07:52:15 25 4
gpt4 key购买 nike

这里有一些关于这个的讨论,但我有一些具体的问题我无法找到答案。所以,直呼,我的意思是 =>T类型,0-arity 函数我的意思是 () => T
我理解(我认为)概念上的差异,但可能我遗漏了一些东西,因为我还有很多问题:

  • 为什么会有=>T这个概念如果我们总是可以使用 () => T ?
  • 每个都有语法/功能限制吗?目前我只发现 =>不能用作类字段。这是唯一的限制吗?
  • 两者生成的代码是否总是相同的?
  • 我应该总是更喜欢=>T ?为什么?
  • 调用=>T 是否正确?一种?在我看来,它在 scala 中没有任何类型表示。
  • 最佳答案

    1)使用它更方便,尤其是在 DSL 中:

    def printAndGet[T](f: => T) = {
    val res = f
    println(res + " printed")
    res
    }

    scala> :paste
    // Entering paste mode (ctrl-D to finish)

    val k = printAndGet {
    val a = 5
    5 * a
    }

    // Exiting paste mode, now interpreting.

    25 printed
    k: Int = 25

    2) => T只能是方法或函数的参数。实际上 => T() => T不可互换:
    scala> def aaa(f: => String) = f
    aaa: (f: => String)String

    scala> val a: Function1[() => String, String] = aaa _
    <console>:8: error: type mismatch;
    found : (=> String) => String
    required: (() => String) => String
    val a: Function1[() => String, String] = aaa _
    ^

    感谢@som-snytt,找到了这个:
    scala> object O { def f(i: Int) = i; def f(i: => Int) = i + 1 }
    defined object O

    scala> O.f(5)
    res12: Int = 5

    scala> O.f(5: (=> Int))
    <console>:1: error: no by-name parameter type allowed here
    O.f(5: (=> Int))
    ^

    即使它可以编译也应该工作 - 但它没有(scala 2.11.2、2.11.5 REPL 只是崩溃):
    scala> val k: (=> Int) => Int = O.f _
    k: (=> Int) => Int = <function1>

    scala> k(5) //should be 6
    res18: Int = 5 //WTF?

    最后一个似乎是一个错误

    3)不完全一样,如果你想要相同,只需转换 => T进入 () => T :
    scala> def aaa(f: => String) = {f _}
    aaa: (f: => String)() => String

    字节码也可能不同。例如,编译器更有可能内联来自 => T 的代码。没有为它生成 lambda。所以,关键区别在于 () => T实际上是一个对象(一等公民), => T不是。

    4) 参见 1,但有时您可能需要确保用户知道计算可能会延迟 - () => T那么更好。

    5)它是类型签名的一部分,只需查看 eta-expansion:
    scala> def aaa(f: => String) = {f}
    aaa: (f: => String)String

    scala> aaa _ //convert method into a function
    res7: (=> String) => String = <function1>

    scala> val a: ( => String) => String = aaa _
    a: (=> String) => String = <function1>

    但是 scala 不将其识别为独立类型:
    scala> val a: Function1[( => String), String] = aaa _
    <console>:1: error: no by-name parameter type allowed here
    val a: Function1[( => String), String] = aaa _
    ^

    关于scala - 关于按名称调用和 0-arity 函数之间区别的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32802104/

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