2010-09-01 18 views
5

Kiedy próbuję pominąć punkty od sposobu wywołania, jak w tym przykładzie programu:Co oznacza "typ rekursywny <method name>" w Scali?

object Test extends Application { 
    val baz = new Baz 
    var foo = baz bar 
    println(foo) 
} 

class Baz { 
    def bar = "bar" 
} 

otrzymuję dziwne błędy. Pierwszy to error: recursive method foo needs type: println foo, a drugi to error: type mismatch; found: Unit, required: Int, println(foo). Pierwszy błąd został naprawiony w jakiś dziwny sposób, gdybym określił, że typem foo powinien być String. Drugi nie zniknie, zanim wstawię kropkę między baz i bar. Jaka jest tego przyczyna? Dlaczego Scala uważa, że ​​baz bar jest metodą rekursywną?

+0

Podobne: http://stackoverflow.com/questions/2246212/why-does-scalas-semicolon-inference-fail-here – missingfaktor

Odpowiedz

7

Problemem jest to, że jeśli pominiesz kropki, kod jest niejednoznaczny. Kompilator leczenia ekspresji jako

var foo = baz.bar(println(foo)) 

zatem foo określa się rekurencyjnie i StringOps.apply metoda wymaga Int argument (String będzie pośrednio przekształca się StringOps jak String ma apply metody).

Powinieneś używać tylko operatora jak składni podczas wywoływania metod, które przyjmują jeden argument inny niż Unit, aby uniknąć takich niejednoznaczności.

+0

Dziękuję bardzo za odpowiedź. Nie miałem pojęcia, że ​​Scala będzie próbowała tak układać linie. Myślałem, że potraktował kresy jako średnik. Eksperymentowałem trochę, a problem mógł zostać rozwiązany przez wstawienie średnika po 'val foo = bazbar'. – mranders

+0

Scala zwykle traktuje podziały wierszy jako białe znaki, ale kompilator próbuje odczytać średniki w razie potrzeby. W twoim przypadku to nie działa dobrze razem z wnioskiem typu. – Moritz