Scala 对按名称调用参数的隐式转换的工作方式因函数是否重载而异

标签 scala implicit-conversion callbyname

让我们看看下面的代码:

import scala.language.implicitConversions
class Foo
implicit def int2Foo(a: => Int): Foo = new Foo
def bar(foo: Foo) = {}
def bar(foo: Boolean) = {}
bar {
  println("Hello")
  64
}

此代码不打印任何内容,因为该块包含 println("Hello")视为 => Int并转换为 Foo来自 int2Foo .但是如果我们省略重载函数bar(foo: Boolean),就会发生令人惊讶的事情。
import scala.language.implicitConversions
class Foo
implicit def int2Foo(a: => Int): Foo = new Foo
def bar(foo: Foo) = {}
bar {
  println("Hello")
  64
}

这打印 Hello因为它计算块,而且只计算最后一条语句,64在这种情况下, 被视为按名称调用参数。我无法理解这种差异背后存在什么样的理由。

最佳答案

我认为 Scala 规范对于如何在此处应用隐式 View 是模棱两可的。换句话说,声明的以下两种解释都符合规范:

bar { println("Hello"); int2Foo(64) }
bar { int2Foo({ println("Hello"); 64 }) }

当然,不相关的重载影响这种行为是非常违反直觉的。在我看来,这种行为虽然模棱两可,但至少应该是一致的。这必须是重载解析、按名称参数和隐式 View 之间编译器交互的实现细节。我已提交 SI-9386来解决这个问题。

关于Scala 对按名称调用参数的隐式转换的工作方式因函数是否重载而异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31271662/

相关文章:

java - 基于Java DataFrame去除重复行

c - 这个指针应该这样操作吗?基础C

c++ - 隐式转换限制

c - 与负数比较时,为什么 sizeof 运算符会发生这种情况?

scala - 在按名称参数 : evaluation is not forced? 中传递的函数上使用 apply ("()")

mysql - FlywayDB : Migration fails with "Error executing statement", 但手动运行迁移 SQL 代码有效

scala - 如何在 Spark 2.1 中保存分区的 Parquet 文件?

scala - Akka 事件总线教程

c++ - 按名称调用/按值调用

scala - 如何使用ScalaMock模拟按名称调用参数(如getOrElse)?