2011-09-21 3 views
25

È possibile creare una classe con un riferimento immutabile a un oggetto partner oppure deve essere un var che si assegna dopo la creazione?Instantiating di oggetti accoppiabili immutabili

ad es.

class PairedObject (p: PairedObject, id: String) { 
    val partner: PairedObject = p // but I need ref to this object to create p! 
} 

o analogamente, come è possibile creare un'istanza della coppia successiva?

class Chicken (e: Egg) { 
    val offspring = e 
} 

class Egg (c: Chicken) { 
    val mother = c 
} 

risposta

25

Ecco una soluzione completa al problema di pollo/Egg:

class Chicken (e: =>Egg) { 
    lazy val offspring = e 
} 

class Egg (c: =>Chicken) { 
    lazy val mother = c 
} 

lazy val chicken: Chicken = new Chicken(egg) 
lazy val egg: Egg   = new Egg(chicken) 

Si noti che è necessario fornire i tipi espliciti alle variabili chicken e egg.

E per PairedObject:

class PairedObject (p: => PairedObject, val id: String) { 
    lazy val partner: PairedObject = p 
} 

lazy val p1: PairedObject = new PairedObject(p2, "P1") 
lazy val p2: PairedObject = new PairedObject(p1, "P2") 
+0

Ingegnoso! Testato ... funziona –

+0

Ho aggiunto anche la soluzione per PairedObject. Inoltre ho scoperto che i valori per 'chicken' e' egg' non hanno bisogno di essere pigri. Rigorosamente non è necessario includere i tipi per entrambi, come si può dedurre. –

+9

Questa soluzione funzionerà se inserita al livello più alto di una definizione 'class' o' object', ma si ottiene un errore di riferimento forward illegale se 'chicken' e' egg' sono variabili locali (ad esempio all'interno di una funzione). Una soluzione che funziona in qualsiasi ambito è: 'lazy val (egg: Egg, chicken: Chicken) = ...', che può essere autoreferenziale. –

4

Se il problema è i riferimenti circolari, è possibile utilizzare la soluzione ha scritto in questa domanda SO:

scala: circular reference while creating object?

Questo risolve il problema di pollo/uova.

+0

funziona bene se ho solo un paio di 'caso object's: basta fare la val' lazy'. –