【问题标题】:Scala: ambiguous reference to overloaded definition - best disambiguation?Scala:对重载定义的模棱两可的引用 - 最好的消歧?
【发布时间】:2011-12-05 00:22:38
【问题描述】:

我有一个后续问题,即存在带参数和不带参数的重载方法定义会导致编译错误,这里已经讨论过:Why is this reference ambiguous?

回顾一下:

 trait A { 
    def foo( s: String ) : String
    def foo : String = foo( "foo" )
 }
 object B extends A {
    def foo( s: String ) : String = s
 } 
 B.foo     // won't compile

导致错误信息:

 error: ambiguous reference to overloaded function
 both method foo in object B of type(s: String)String
 and method foo in trait A of type => String
 match expected type Unit
 B.foo

一个可行的解决方案是为编译器提供预期的类型,如下所示:

 val s: String = B.foo

不幸的是,人们可能并不总是想要引入额外的变量(例如在断言中)。在上面引用的早期文章的答案中至少推荐两次的解决方案之一是调用带有空括号的方法,如下所示:

 B.foo()

不幸的是,这会导致类似的编译器错误(Scala 2.9.0.1):

 (s: String)String <and>
 => String
 cannot be applied to ()
 B.foo()

这是一个错误,还是推荐的解决方案有误? 最终:有哪些选择可以简洁地做到这一点,例如:

 assert( B.foo == "whatever" )

而不是

 val expected : String = B.foo
 assert( expected == "whatever" )

谢谢。

【问题讨论】:

  • B 无法编译,因为您忘记在 trait A 中提供 def foo: String 的实现。
  • @agilesteel 对,A 上无参数 foo 的实现在传输中丢失了。现在解决了。错误保持不变。

标签: scala overloading ambiguity


【解决方案1】:

您可以在第二个foo 定义中添加空括号:

trait A { 
  def foo( s: String ) : String
  def foo() : String
}

然后您可以按照其他地方的说明删除歧义:

assert( B.foo() == "whatever" )

【讨论】:

  • 这也是一个很好的答案,谢谢。一个潜在的缺点是,如果无参数 foo() 仅在某些派生类中与重载替代项发生冲突(例如,如果它来自比 A 更高的类),它仍然会强制所有调用,即使在 A 的兄弟姐妹之下,现在使用空括号来调用它(至少如果你不希望你的 IDE 在你离开括号时标记调用)。
【解决方案2】:
assert( (B.foo: String) == "whatever" )

【讨论】:

    猜你喜欢
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2011-06-30
    • 1970-01-01
    相关资源
    最近更新 更多