2015-08-25 23 views

Odpowiedz

8

naprawdę wydaje się jak powinno być w stanie napisać,

trait X[T <: X[T]] 
object Y extends X[Y.type] 

jednak, jeśli spróbujesz, że kompilator daje bezużyteczny (i myślę, że fałszywy) Błąd,

scala> object Y extends X[Y.type] 
<console>:16: error: illegal cyclic reference involving object Y 
     object Y extends X[Y.type] 

Mówię "fałszywy", ponieważ możemy skonstruować równoważny obiekt z odrobiną dodatkowej infrastruktury, Jeśli chciałbyś eksperymentować z tym w prawdziwym kodzie, użycie obiektu pakietu w miejsce object Fix sprawiłoby, że ten idiom byłby trochę bardziej użyteczny.

+0

Czy uważasz, że jest to błąd kompilatora lub jest to niedopatrzenie w specyfikacji? A może jest jakaś subtelność, której nie widzimy, co sprawia, że ​​błąd jest konieczny? –

+3

Rozmowa z @retronym na [scala/scala] (https://gitter.im/scala/scala?at=55dc7303fcfd5a7865af45d4) sugeruje, że jest to błąd. I działa [zgodnie z oczekiwaniami na Dotty] (https://gitter.im/lampepfl/dotty?at=55dc95a3a6bcd8894068e278). –

+0

https://github.com/scala/bug/issues/9844 –

1

go zmienić na:

trait Y extends X[Y] 

object nie jest typem w Scala, ale tzw obiekt towarzysz. Definiując object Y, nie można wyrazić, że powinien on rozciągać się na trait T[Y], ponieważ ten drugi Y odnosi się do typu Y, który nie został zdefiniowany. Można jednak wykonać następujące czynności:

trait Y extends X[Y]   //If you try this on the REPL, do :paste before 
object Y extends X[Y] 

W tym przypadku obiekt Y rozciąga X[Y] gdzie druga cecha Y jest po prostu określić, upewnij się, że o tym pamiętać.

+0

Chciałbym, aby Y został wprowadzony tylko raz i uzyskać dostęp do jego unikalnej instancji, dlatego potrzebuję obiektu. –

+0

Następnie możesz uczynić konstruktor prywatnym za pomocą 'class Y private() extends X [Y]' i upublicznij tylko jedną instancję. – Chirlo