Зависимые типы не работают для конструкторов?
Полезны зависимые от пути типы:
trait Sys {
type Global
}
def foo[S <: Sys](system: S)(global: system.Global) = ()
Почему это не работает для конструкторов?
class Foo[S <: Sys](val system: S)(val global: system.Global)
Или я просто делаю это неправильно?
1 ответ
Это похоже на ошибку для меня. Изменить: нашел его, это SI-5712.
Раздел §5.3.3 SLS гласит:
(пс1) .,, (psn) являются предложениями параметров формальных значений для основного конструктора класса. Область действия параметра формального значения включает в себя все последующие разделы параметра и шаблон t.
Есть исключение:
Однако параметр формального значения может не входить в типы каких-либо родительских классов или членов шаблона класса t.
Но он говорит, что он не может быть частью типов любого из родительских классов или членов, ни одного из следующих разделов параметров, поэтому он не запрещает зависимые от пути типы между группами аргументов.
Вы можете обойти это с помощью вторичного конструктора:
class Foo[S <: Sys] private[this] () {
def this(system: S)(global: system.Global) = this
}
Изменить: этот обходной путь вторичного конструктора не очень хорош: разоблачение system
или же global
стать очень сложным, потому что только основной конструктор может объявить val
s.
Пример с приведением:
class Foo[S <: Sys] private[this] () {
private[this] var _system: S = _
private[this] var _global: system.Global = _
def this(system0: S)(global0: system0.Global) = {
this
_system = system0
_global = global0.asInstanceOf[system.Global]
}
lazy val global: system.Global = _global
lazy val system: S = _system
}
Но это становится ужасно. Предложение @ Senia намного лучше.