2013-02-18 4 views
5

Я искал немного вокруг, но я не смог найти пример такой структуры:Selfreferencing Дженерики

Person[P <: Person[P]] 

, что объясняется таким образом, я понимаю.

Как это решить? Это похоже на бесконечную рекурсию, но, похоже, я ошибаюсь в этом заключении.

ответ

5

Сама структура объясняется в Twitter Scala School и называется F-ограниченным полиморфизмом.

// you define it like this 
trait X extends Person[X] 

// it then gets expanded to this 
trait Person[X extends Person[X]] 

Эта структура используется, когда черта должна иметь ссылку на тип объекта, который он расширяет. Если школа объяснение Scala не достаточно, то вы можете искать в интернете для "F-ограниченных полиморфизмов

+1

F-ограниченный полиморфизм ... да, я бы никогда не смог это найти. Спасибо, мне кажется, я понял это сейчас. –

+0

Где вы используете 'extends' в последней строке, вы имели в виду' <: '? – AmigoNico

+0

Я прыгал взад-вперед, чтобы выбрать один из двух. Как вы думаете, '<:' было бы лучше? – EECOLOR

5

Это иногда называет тип самостоятельной (не следует путать с явно типизированными автомодельными ссылками Scala), и это, как правило, используется для того, чтобы иметь сигнатуры методов, которые достаточно сильны, чтобы выразить, что метод работает с объектами того же типа, что и приемник.

Давайте рассмотрим пример. Скажем, у вас есть базовый признак Animal с общим методом breed, который принимает еще Animal и возвращает Animal.

trait Animal { 
    def breed(a: Animal): Animal 
} 

Хорошо, но то, что вы на самом деле хотите это breed метод, который выражает, что каждое конкретное животное размножается только с животными одного и того же класса, а также возвращает животное одного и того же класса. Следующая реализация

class Cow extends Animal { 
    def breed(c: Cow) = new Cow 
} 

не представляется возможным, потому что подпись это breed «s не соответствует. Переопределение также невозможно, потому что вам нужно будет изменить тип аргумента ковариантно, что запрещено.

Self-типа к спасению:

trait Animal[A <: Animal[A]] { 
    def breed(a: A): A 
} 

class Cow extends Animal[Cow] { 
    def breed(c: Cow) = new Cow 
} 

Как EECOLOR уже отмечалось, теория типа позади него называется F-ограниченный полиморфизм.

+0

спасибо, например, вместе со ссылкой от EECOLOR Я думаю, что я действительно понимаю, что это хорошо для кода, который у меня передо мной ^^ –

Смежные вопросы