Учитывая определение класса с параметром связанного типа Animal[A <: String]
кажется, что компилятор Scala не делает вывод B <: String
от Animal[B]
. Можно ли сделать вывод? Как помочь компилятору сделать вывод?Как определить классы case с членами с несвязанными параметрами типа?
Ниже приведен конкретный пример с примерами классов, где недостаток этого вывода является проблемой.
Рассмотрим следующую иерархию классов: случай
sealed trait Person[+T <: Person[T]]
case class Student() extends Person[Student]
case class Professor() extends Person[Professor]
Мне нужно определить тематическое класс University
, который я могу создать экземпляр с переменной типа Person[_]
, например val p: Person[_] = Student()
. Я думал, что это будет работать со следующим определением:
case class University(p: Person[_])
Но это не удается компиляции с ошибкой:
type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]]
Если я связать параметр типа в случае класса University
компилирует (он также компилирует с неограниченные параметры, если я уронить case
ключевое слово, но это не вариант в моем случае):
case class BoundUniversity[P <: Person[P]](p: Person[P])
но эта параметрическая версия не может быть экземпляр с неограниченным переменным типа Person[_]
:
val p: Person[_] = Student()
BoundUniversity(p)
не удается составителем с:
inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]]
Той же ошибка происходит из-за метод со связанным аргументом, таким как:
def general[P <: Person[P]](p: P) = println(p)
так это не специфичные для конструкторов классов.
Два вопроса:
Тип
Person
определяется с параметрами границPerson[+T <: Person[T]]
, так что каждый экземпляр данного типа застрахована соблюдать эти границы:val p: Person[P]
означает, чтоP <: Person[P]
; или я что-то упускаю? Итак, как я могу сделать это понятным для компилятора, чтобы он не жаловался?Как я могу определить класс case с членами с несвязанным параметром типа, например
case class University(p: Person[_])
?
Должен ли 'T' быть ковариантным? – leedm777
@ dave в моем конкретном случае 'T' должен быть ковариантным, но я думаю, что это не меняет проблемы: см. Вводный пример. –
Вы можете получить где-нибудь, используя [абстрактные типы] (http://docs.scala-lang.org/tutorials/tour/abstract-types.html), но затем они становятся [почти инвариантными] (http: // stackoverflow. ком/а/5359015/115 478). – leedm777