2011-09-21 26 views
25

Có thể tạo một lớp có tham chiếu không thay đổi được đối tượng đối tác không, hoặc nó có phải là var mà tôi gán sau khi tạo không?Lập tức các đối tượng ghép nối không thay đổi

ví dụ:

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

hoặc tương tự như thế nào tôi có thể khởi tạo cặp sau?

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

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

Trả lời

25

Đây là một giải pháp hoàn chỉnh cho vấn đề gà/trứng:

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) 

Lưu ý rằng bạn phải cung cấp các loại rõ ràng để các biến chickenegg.

Và đối với 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

Khéo léo! Thử nghiệm ... hoạt động –

+0

Tôi cũng đã thêm giải pháp cho PairedObject. Ngoài ra tôi thấy rằng vals cho 'gà' và' trứng' không cần phải lười biếng. Nghiêm túc bạn không cần phải bao gồm các loại cho cả hai, như một có thể được suy ra. –

+9

Giải pháp này sẽ hoạt động nếu được nhập ở cấp cao nhất của định nghĩa 'class' hoặc' object', nhưng một lỗi tham chiếu chuyển tiếp bất hợp pháp nếu 'chicken' và' egg' là các biến cục bộ (ví dụ, bên trong một hàm). Một giải pháp hoạt động trong bất kỳ phạm vi nào là: 'lazy val (trứng: trứng, gà: gà) = ...', có thể tự tham khảo. –

4

Nếu vấn đề của bạn là tham chiếu vòng tròn, bạn có thể sử dụng giải pháp posted in SO câu hỏi này:

scala: circular reference while creating object?

này giải quyết vấn đề gà/trứng.

+0

trình tốt nếu tôi chỉ có một vài trường hợp của 'object's: chỉ cần thực hiện val 'lazy'. –

Các vấn đề liên quan