Scala 歧义与无括号函数调用

Bor*_*lid 6 scala

原谅冗长的设置。这个问题与Scala相关,但没有得到回答:对重载定义的模糊引用 - 最佳消歧?.

我对 Scala 很陌生,让我失望的一件事是 Scala:

  • 拥有一流的功能
  • 使用对象点表示法而不带任何括号参数列表时调用函数(就像函数是属性一样)

这两种语言特性让我很困惑。看下面的代码:

类我的类{
    def something(in: String): String = {
        在 + "_X"
    }

    定义一些东西:字符串 => 字符串 = {
        案例_ =>“固定”
    }
}

val my = new MyClass()

println(List("foo", "bar").map(my.something))

我希望List("foo_X", "bar_X")通过调用somethingmap's requiredString => ?参数匹配的原型来打印。相反,输出是List("Fixed", "Fixed")- Scala 2.11 正在调用无参数something(),然后将其返回值传递给map.

如果我们注释掉 的第二个无参数原型something,输出变为预期结果,证明另一个原型在上下文中是有效的。

向第二个原型添加一个空参数列表(制作它def something())也会改变行为。

改变my.somethingtomy.something(_)唤醒 Scala 到它之前默默忽略的歧义:

错误:对重载定义的引用不明确,
这两种方法都在类 MyClass 中的类型 => String => String
和方法类 MyClass 中的类型 (in: String)String
匹配参数类型(字符串)
println(List("foo", "bar").map(my.something(_)))

即使使用据称为此目的的魔法尾随下划线也不起作用:

val myFun: (String) => String = my.something _

这导致:

错误:类型不匹配;
 找到:() => 字符串 => 字符串
 必需:字符串 => 字符串
val myFun: (String) => String = my.something _

我的问题:

  • 如果我MyClass完全按照所写的那样(原型没有更改,特别是没有向其中一个原型添加空参数列表),我如何明确地告诉 Scala 我希望第一个单参数版本something作为参数传递到另一个电话?
  • 既然显然有两个令人满意的参数可以传递给map,为什么 Scala 编译器没有将歧义报告为错误?
  • 有没有办法禁用 Scala 的(有时,并非总是)foo.bar视为等同于的行为foo.bar()

Bor*_*lid 2

我已经在 Scala 问题跟踪器上提交了一个错误,并且共识似乎是这种行为是一个错误。编译器应该抛出有关对“my.something”的模糊引用的错误。