7

Immaginiamo i seguenti articoli nel campo di applicazione:inferenza di tipo nella lista degli argomenti in combinazione con setter non funzionante

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

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

La seguente non riesce a compilare:

perform(Thing.data = _) 

Il messaggio di errore è:

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

Mentre il seguente compila:

perform(Thing.data_=) 

Da allora ho superato questo problema creando un'astrazione migliore, ma la mia curiosità rimane ancora.

Qualcuno può spiegare perché questo è?

+0

'T' viene fuori dal nulla. Si suppone che sia un parametro di tipo per il metodo 'process' –

risposta

3

Facciamo espandere ciò che si sta facendo nel primo esempio:

Thing.data = _ 

è una scorciatoia per la definizione di una funzione anonima, che si presenta come:

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

Così, quando si chiama

perform(Thing.data = _) 

è lo stesso di

perform(anon) 

Il problema è anon e perform prendere un parametro di tipo T e in nessun punto stai dichiarando ciò che è T. Il compilatore può inferire solo i parametri di tipo in una chiamata di funzione dagli argomenti passati, non dal corpo della funzione, quindi non può dedurre in anon che T deve essere String.

Si noti che se si chiama

perform[String](Thing.data = _) 

il compilatore non ha alcun problema, perché ora sa che cosa T dovrebbe essere, e se si tenta di utilizzare qualsiasi tipo oltre stringa, si otterrà un errore di tipo non corrispondente, ma l'errore si verifica nel corpo della funzione anonima, non sulla chiamata a perform.

Tuttavia, quando si chiama

perform(Thing.data_=) 

si sta passando il metodo Thing.data_=, che è esplicitamente definito come Box[String] => Unit, in modo che il compilatore può inferire 's parametro di tipo perché proviene da un argomento di funzione perform .

+0

Grazie per la risposta. Un manifest può far sì che [String] non sia più richiesto quando si usa 'perform (Thing.data = _)'? – Scoobie

Problemi correlati