7

Wyobraźmy sobie następujące elementy w zakresie:typ wnioskowanie w liście argumentów w połączeniu z seter nie działa

object Thing { 
    var data: Box[String] = Empty 
} 

def perform[T](setter: Box[T] => Unit) { 
    // doesn't matter 
} 

Poniżej nie kompilacji:

perform(Thing.data = _) 

Komunikat o błędzie jest:

<console>:12: error: missing parameter type for expanded function ((x$1) => Thing.data = x$1) 
       perform(Thing.data = _) 
           ^
<console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error. 
       perform(Thing.data = _) 
           ^

Podczas następujących kompilacji:

perform(Thing.data_=) 

Od tego czasu przekroczyłem tę kwestię, tworząc lepszą abstrakcję, ale moja ciekawość nadal istnieje.

Czy ktoś może wyjaśnić, dlaczego tak jest?

+0

'T' wychodzi znikąd. Czy ma to być parametr typu do metody 'process' –

Odpowiedz

3

Niech rozwijać się, co robisz w pierwszym przykładzie:

Thing.data = _ 

jest skrótem dla definiowania anonimową funkcję, która wygląda tak:

def anon[T](x: Box[T]) { 
    Thing.data = x 
} 

Więc kiedy dzwonisz

perform(Thing.data = _) 

to to samo, co

perform(anon) 

Problemem jest anon i perform podjąć parametr typu T i w żadnym momencie jesteś deklarowania co T jest. Kompilator może jedynie wnioskować o parametrach typu w wywołaniu funkcji z przekazanych argumentów, a nie z wnętrza funkcji, więc nie może wywnioskować, że w anon musi być powinien być String.

Zauważ, że jeśli zadzwonisz

perform[String](Thing.data = _) 

kompilator nie ma problemu, ponieważ teraz nie wie, co T powinno być, a jeśli spróbujesz użyć dowolnego typu oprócz napisu, dostaniesz błąd rodzaj niezgodności, ale błąd występuje w treści anonimowej funkcji, a nie w wywołaniu do perform.

Jednak kiedy zadzwonić

perform(Thing.data_=) 

są przechodzącą metodę Thing.data_=, która jest wyraźnie zdefiniowany jako Box[String] => Unit, więc kompilator może wywnioskować perform „s parametr typu, ponieważ pochodzi z argumentem funkcji .

+0

Dzięki za odpowiedź. Czy manifest może sprawić, że [String] nie będzie już potrzebny przy użyciu 'perform (Thing.data = _)'? – Scoobie

Powiązane problemy