Scala: двусмысленная ссылка на перегруженное определение - лучшее значение? - PullRequest
2 голосов
/ 11 октября 2011

У меня есть дополнительный вопрос к проблеме, что наличие перегруженных определений методов с параметрами и без параметров приводит к ошибке компиляции, которая уже обсуждалась здесь: Почему эта ссылка неоднозначна?

Подведем итог:

 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" )

Спасибо.

Ответы [ 2 ]

6 голосов
/ 11 октября 2011
assert( (B.foo: String) == "whatever" )
2 голосов
/ 11 октября 2011

Вы можете добавить пустые скобки ко второму foo определению:

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

Затем вы можете удалить неоднозначность, как описано в другом месте:

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