Как @cchantep упоминалось в своем комментарии, self : T
в этом случае самостоятельно тип аннотации в основном говорят, что экземпляр Foo[T]
потребностей также вести себя как T
. Вы можете видеть, что это действительно так в FooImpl
, как FooImpl <: Foo
.
Вы можете узнать больше о аннотации типа 1 here, here или here. Обратите внимание, что в большинстве случаев вы увидите, что он используется в контексте Injection Dependency и Pattern Cake.
Самое интересное из the second link, я думаю, что начальный участок:
Другими словами, какой смысл делать это:
trait A
trait B { this: A => }
, когда вы могли бы вместо того, чтобы просто сделать это:
trait A
trait B extends A
Почему вы должны использовать [этот синтаксис]?
[...] Ответ обычно сводится к «B, требующему A» (аннотации) против «B, являющегося A» (наследование), и что первое лучше для управления зависимостями.
И наконец, и для уточнения, обратите внимание, что слово self
не требуется вообще. Это может быть любое допустимое имя переменной, но self
или this
в большинстве случаев являются конвенцией. То есть, вы могли бы делать:
trait A
trait B { myVar: A => }
но это было бы реже.
Это сам тип, который гарантирует, что любой подтип 'Foo' должен быть параметром типа, заданным' Foo' – cchantep