2015-08-26 5 views
11

Sono confuso sul motivo per cui Scala si sta lamentando di questo codice. Ho due classi che dipendono l'una dall'altra. Quando provo a creare una nuova istanza di A senza una dichiarazione di tipo, il codice non verrà compilato.Il valore ricorsivo xxx richiede il tipo in Scala

class A(b:B) { 

    } 

    class B(a:A){ 

    } 

    val y = new A (new B(y)); // gives recursive value y needs type 

    val z:A = new A (new B(y)); // ok 

Perché il compilatore non conosce il tipo di y quando ho dichiarato come new A ?

+0

Correggetemi se ho torto, l'ultima riga non deve essere anche "val y: A = nuova A (nuova B (y))?"? Sono un po 'confuso perché quel 'z' è lì. – Dean

risposta

8

Per inferire il tipo di y, il compilatore deve prima determinare il tipo di valore sul lato destro dell'assegnazione. Durante la valutazione del tipo della mano destra, incontra il riferimento alla variabile che è (al momento) ancora di tipo sconosciuto. Quindi il compilatore rileva un ciclo "tipo di dipende dal tipo di " e non riesce.

Nel secondo esempio, questa situazione non si verifica perché quando si valuta il tipo di new A(new B(y)), è già noto il tipo di e riesce.

Edit: quando il tipo di modo ricorsivo utilizzato y esigenze variabili per includere un tratto misto-in, può essere dichiarato in questo modo:

val y : A with Mixin = new A(new B(y)) with Mixin 
+0

Ma questo renderebbe impossibile mixare un tratto quando devo dichiarare il tipo di ** y ** perché y sarà sempre di tipo A e non vedrà mai i metodi dei tratti. Dovrei lanciarlo tutto il tempo! – Jay

+1

Se intendete aggiungere mixin ad A, allora dovreste essere in grado di fare 'y: A con Mixin = new A (new B (y)) con Mixin' – Mifeet

+0

Oh mi mancava il con nella dichiarazione – Jay

2

È possibile specificare il tipo di y specifico e sarà compile:

val y : A = new A(new B(y)) 
Problemi correlati