2015-09-23 7 views
1

type несоответствие; найдено: IDataContext [_ $ 1], где type _ $ 1 <: DBObject требуется: IDataContext [DBObject] Примечание: _ $ 1 <: DBObject, но класс IDataContext является инвариантным по типу A. Вместо этого вы можете определить A как + A. (SLS 4.5)scala - еще другой тип несоответствие

Эта проблемная часть «требуется: IDataContext [DBObject]» на самом деле определяется следующим образом.

abstract class IDataContextBuilder[+A <: DBObject] { 

    def initXDataPoints(dataContext: IDataContext[A]): Unit 
} 

Я изменил его на следующий и он работает, но он выглядит совершенно излишнее

abstract class IDataContextBuilder[+A <: DBObject] { 

    def initXDataPoints[A <: DBObject](dataContext: IDataContext[A]): Unit 
} 

Сейчас проблема заключается в реализации выше метода:

override def initXDataPoints[Dim1Agg](dataContext: IDataContext[Dim1Agg]): Unit = { ...} 

метод initXDataPoints не отменяет ничего. Примечание: супер классы класса Dim1DataContextBuilder содержит следующий не конечные член названных initXDataPoints: Защита initXDataPoints [A <: DBObject] (DataContext: IDataContext [A]): ​​Unit

Dim1Agg является подтип DBObject

ответ

1

Глядя при первом фрагменте кода я думаю, что у вас есть проблема с дисперсией: параметр типа A является ковариантным (определяется с помощью +), однако он отображается в противоположном варианте - аргумент dataContext по методу initXDataPoints. Что вы можете сделать, это параметризировать initXDataPoints с нижней границей так:

def initXDataPoints[B >: A](dataContext: IDataContext[B]): Unit 

Edit:

trait DBObject 
trait Dim1Agg extends DBObject 
trait IDataContext[A] 

abstract class IDataContextBuilder[+A <: DBObject] { 
    def initXDataPoints[B>:A](dataContext: IDataContext[B]): Unit 
} 

class Dim1DataContextBuilder extends IDataContextBuilder[Dim1Agg] { 
    override def initXDataPoints[B >: Dim1Agg](dataContext: IDataContext[B]): Unit = ??? 
} 

Обоснованием добавив нижнюю границу параметра типа B является то, что реализация не сможет используйте любые специфические свойства типа A. Использование определенных свойств A может нарушаться под наследованием и поэтому запрещено компилятором scala. Это очень хорошо объясняется в книге «Программирование в Scala 2nd edition Chapter 19 (параметризация типа). Я предлагаю прочитать всю главу и искать конкретный пример, который объясняет это в разделе 19.4.

+0

Я думаю, что это правильное решение, но когда я параметризуюсь с помощью [A <: DBObject], что на самом деле произошло? Ошибка компиляции ушла в тот момент, но затем я попал в другую ошибку, как я объяснил в OP. Что за это разумно? – nir

+0

Я думаю, вы хотите параметризовать класс Dim1DataContextBuilder с дочерним классом Dim1Agg. Тогда переопределение initXDataPoints будет простым. Что-то вроде этого: –

+0

Хорошо работает. но я до сих пор не понимаю, почему моя версия метода 'def initXDataPoints [A <: DBObject] (dataContext: IDataContext [A]): ​​Unit' больше не компилирует ошибку о контравариантной позиции. – nir

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