Вложенная черта в конструкторе класса в scala - PullRequest
7 голосов
/ 03 сентября 2010

Я играю со скалой (скала 2.8). Предположим, у меня есть класс с вложенной чертой, и я хочу использовать эту вложенную черту в качестве типа параметра в конструкторе класса. Это вообще возможно? Это самое близкое, что я пришел:

class OuterClass(traitParam:OuterClass#InnerTrait) {
  trait InnerTrait { }
  val y:InnerTrait = traitParam
}

Без третьей строки, которая даже компилируется, но как только я пытаюсь использовать traitParam как InnerTrait, я получаю ошибку компилятора:

несоответствие типов; найдено: OuterClass # InnerTrait требуется: OuterClass.this.InnerTrait.

Я не могу понять, что (если что) я мог бы сделать. Doing

class OuterClass(traitParam:OuterClass.this.InnerTrait)

вместо этого, как может указывать сообщение об ошибке, не компилируется. Есть ли у меня другой выбор, кроме как переместить InnerTrait за пределы OuterClass? Если вам интересно, почему я хотел бы сделать это, ответ заключается в том, что в моем реальном коде эквивалент OuterClass имеет параметры типа, которые затем будут использоваться в InnerTrait. Если я вывожу его наружу, то мне придется пересчитывать параметры типа каждый раз, когда я ссылаюсь на внутреннюю черту.

Ответы [ 2 ]

7 голосов
/ 03 сентября 2010

Вы сталкиваетесь с зависимыми от пути типами Scala .тип вашего val y: InnerTrait зависит от экземпляра, в котором он содержится.OuterClass#InnerTrait - это супертип всех существовавших InnerTrait для всех экземпляров OuterClass.

Попробуйте поработать с этим:

class OuterClass(traitParam: OuterClass#InnerTrait) {
    trait InnerTrait { }

    type IT = OuterClass#InnerTrait

    def m1: IT = traitParam
}
1 голос
/ 03 сентября 2010

OuterClass имеет параметры типа, которые будет затем использоваться в InnerTrait

Таким образом, возможно иметь a: OuterClass и b: OuterClass, чтобы эти параметры типа были разными. Например:

abstract class OuterClass[T] {
  val x: T
}

val a = new OuterClass[Int] { val x = 5 }
val b = new OuterClass[String] { val x = "abc" }

Так вот загадка ... InnerTrait должен быть привязан к экземпляру OuterClass, поскольку каждый экземпляр может иметь свой параметр типа. Однако вы хотите передать InnerTrait в качестве параметра конструктору OuterClass, поэтому вам нужно будет создать InnerTrait перед OuterClass. Но так как InnerTrait должен быть привязан к экземпляру OuterClass, то OuterClass должен быть построен до InnerClass, превращая это в проблему курицы и яйца.

В этом дизайне есть что-то странное, поэтому я предлагаю вам переосмыслить его.

...