Требуется разъяснение по поводу дисперсии Scala и границ типов - PullRequest
4 голосов
/ 05 марта 2012

У меня есть черта scala, определенная следующим образом:

trait AdvertisementDAO[A <: Advertisement] extends CrudRepository[A, Integer] {
...

Я бы хотел получить экземпляр этого DAO, который работал бы для обоих подклассов класса объявления или самого базового класса объявления . Я не уверен, как добиться желаемого эффекта.

Вот что я попробовал:

@Inject
var advertisementDAO: AdvertisementDAO[+Advertisement] = _

Может кто-нибудь помочь?

Ответы [ 2 ]

3 голосов
/ 12 апреля 2012

Похоже, вы пытаетесь определить параметр типа A признака AdvertisingDAO как ковариантный. Ниже приведен вариант примера кода из предыдущего ответа с использованием ковариационной аннотации +.

trait Advertisement {}

class AdvertisementImpl extends Advertisement{}

class CrudRepository[+A,B]  {}

trait AdvertisementDAO[+A <: Advertisement] extends CrudRepository[A, Integer] {}

class AdvertisementDAOImpl[+A <: Advertisement] extends AdvertisementDAO[A]{}

class AdvertisementDAOImpl2 extends AdvertisementDAO[AdvertisementImpl]{}

class AdvertisementDAOImpl3 extends AdvertisementDAO[Advertisement]{}

object Tester
{
  def main(args:Array[String]):Unit =
  {
    var advertisementDAO: AdvertisementDAO[Advertisement] = null
    advertisementDAO = new AdvertisementDAOImpl
    advertisementDAO = new AdvertisementDAOImpl2 
    advertisementDAO = new AdvertisementDAOImpl3
  }
}

Другим примером ковариантного универсального шаблона является scala.collection.immutable.List. Определение общего (класса или признака) C как ковариантного означает, что C [S] является подтипом C [T], если тип S является подтипом типа T. Например, AdvertisingDAO [AdvertisingImpl] является подтипом AdvertisingDAO [Advertising ] потому что AdvertisingImpl является подтипом Advertising (так как AdvertisingImpl расширяет Advertising). Я опубликовал статью , в которой содержится учебник по дисперсии, как это происходит во многих языках (например, Scala, C #, Java). Слайды также доступны для быстрого обзора. Надеюсь, это поможет.

2 голосов
/ 06 марта 2012

Я перепробовал много комбинаций, но получаю ту, которая компилируется с помощью scala 2.9.1

  var advertisementDAO: AdvertisementDAO[_ <:Advertisement] = _

  advertisementDAO = new AdvertisementDAOImpl

  advertisementDAO = new AdvertisementDAOImpl2 

  advertisementDAO = new AdvertisementDAOImpl3

Мой код:

trait Advertisement {}

class AdvertisementImpl extends Advertisement{}

class CrudRepository[A,B]  {}

trait AdvertisementDAO[ A <: Advertisement] extends CrudRepository[A, Integer] {}

class AdvertisementDAOImpl[A <: Advertisement] extends AdvertisementDAO[A]{}

class AdvertisementDAOImpl2 extends AdvertisementDAO[AdvertisementImpl]{}

class AdvertisementDAOImpl3 extends AdvertisementDAO[Advertisement]{}
...