7
Arbeits

Lassen sie die folgenden Elemente in Rahmen vorstellen:Typinferenz in Argumentliste in Kombination mit Setter nicht

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

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

Die folgenden nicht kompilieren:

perform(Thing.data = _) 

Die Fehlermeldung lautet:

<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 = _) 
           ^

Während die folgenden kompiliert:

perform(Thing.data_=) 

Ich habe seitdem dieses Problem durch die Schaffung einer besseren Abstraktion übertroffen, aber meine Neugier bleibt immer noch.

Kann jemand erklären, warum das ist?

+0

'T' kommt aus dem Nichts. Soll es sich um einen Typparameter für die Methode 'process' handeln –

Antwort

3

Lassen Sie uns erweitern, was Sie im ersten Beispiel tun:

Thing.data = _ 

ist eine Abkürzung eine anonyme Funktion für die Definition, die wie folgt aussieht: So

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

, wenn Sie anrufen

perform(Thing.data = _) 

es ist das gleiche wie

perform(anon) 

Das Problem ist anon und perform nehmen einen Typparameter T und an keiner Stelle erklären Sie, was T ist. Der Compiler kann Typparameter nur in einem Funktionsaufruf von übergebenen Argumenten und nicht innerhalb des Funktionskörpers ableiten, so dass er in anon nicht ableiten kann, dass TString sein sollte.

Beachten Sie, dass, wenn Sie

perform[String](Thing.data = _) 

der Compiler kein Problem hat nennen, weil es das, was jetzt weiß T sein sollte, und wenn Sie versuchen, jede Art neben Zeichenfolge zu verwenden, erhalten Sie einen Typenkonfliktfehler erhalten, Der Fehler tritt jedoch im Hauptteil der anonymen Funktion auf, nicht beim Aufruf von perform.

jedoch, wenn Sie anrufen

perform(Thing.data_=) 

Sie die Methode sind vorbei Thing.data_=, die explizit als Box[String] => Unit definiert ist, so dass der Compiler kann infer perform ‚s-Typ Parameter, weil es von einem Funktionsargument kommt .

+0

Danke für die Antwort. Könnte ein Manifest es so machen, dass der [String] nicht länger benötigt wird, wenn "perform (Thing.data = _)" verwendet wird? – Scoobie