gpt4 book ai didi

Scala 名称混淆调用

转载 作者:行者123 更新时间:2023-12-04 13:44:05 26 4
gpt4 key购买 nike

我正在使用 REPL 处理一些按名称调用的示例,并在 Eclipse 中运行相同的示例。

这是 Eclipse 中的内容:
场景一:

val funct = {println("Calling funct")}
takesFunct(funct)

def takesFunct(f: => Unit)
{
val b = f
}

输出为:调用函数

场景二:
方法 takeFunct 保持不变
takesFunct({println("Calling funct")}

输出是:
调用函数
调用函数

斯卡拉 REPL
场景一:
scala> def takesFunct(f: => Unit)
{
val b = f
}
takesFunct: (f: => Unit)Unit

scala> val funct = {println("Calling funct")}
Calling funct
funct: Unit = ()

scala> takesFunct(funct)
// No Output

方案 2
与上面定义的方法相同
scala> takesFunct({println("Calling funct")}
Calling funct

两个问题
1) 为什么 Eclipse 的输出与 REPL 不同?
2)传入和传入有什么区别
val funct = {...}
takesFunct(funct)


takesFunct({...})

最佳答案

在@IttayD 的回答后更新:

Eclipse 上的场景 1 是正确的,您将在下面看到原因。场景 2 显然是一个 Eclipse 错误。 Eclipse 上的 ScalaIDE 以其 splinter 性而闻名。我不会相信它(或使用它)。如果必须,请使用 Intellij IDEA 的 Scala 插件。

你的两个问题的答案是,{}是一个返回其最后一条语句的返回类型的 block 。和 Scheme 的 (begin) 完全一样或 Common Lisp 的 (progn) .当你有:

scala> def takesFunct(f: => Unit)
{
val b = f
}
takesFunct: (f: => Unit)Unit

scala> val funct = {println("Calling funct")}
Calling funct
funct: Unit = ()

scala> takesFunct(funct)
// No Output
funct的 RHS 已被热切评估并返回值 ()类型 Unit发挥作用。将已计算的值应用于按名称调用的函数并在主体中使用它不会导致重新评估,因为该值已经是叶子。

进一步更新:
def takesFunct(f: => Unit)

具有基本相同的语义
def takesFunct(f: () => Unit)

这在某些圈子中称为流式评估或延迟评估。但是,有一个主要区别在于您调用提供的参数的方式。在后一种情况下,为了从 f 中取回一个值,您必须这样调用它 - 即 f() .在前一种情况下, f懒惰的表达它在第一次被引用时评估为一个值,因此是按名称调用的。你可以想到语法 f: => Unit作为一种将您提供的任何表达式自动包装在容器中的方法 {} .使用时检索其内容,如下所示:
scala> val a = { 1 } // 1 wrapped in {}, and retrieved when assigned to a
a: Int = 1

那么这个呢?
scala> takesFunct({println("Calling funct")})
Calling funct

这是因为现在您正在就地创建一个绑定(bind)到函数参数 f 的 block 。 ,并且只有在 val b = f 中使用时才会评估.让我们再做一个实验:
scala> takesFunct(println("Calling funct"))
Calling funct

你怎么问?因为 println(...)被包裹在 {}绑定(bind)到 f .引用 f检索容器内的值,即 println(...) 的值,即 ():Unit .在前面的示例中, f绑定(bind)到 { { println(...) } } , 与 { println(...) } 相同,所以你得到相同的结果。其实你可以嵌套 {}无限期地,仍然得到同样的东西。唯一的区别是,手动提供 {}让您可以像这样在里面放置多个语句:
scala> takesFunct({ println("hello"); println("world") })
hello
world

希望这可以帮助。

关于Scala 名称混淆调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4986557/

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