Требуется разъяснение о дисперсии Scala и границах типов

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

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

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

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

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

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


person balteo    schedule 05.03.2012    source источник


Ответы (2)


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

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. Например, AdvertisementDAO[AdvertisementImpl] является подтипом AdvertisementDAO[AdvertisementImpl]. ] потому что AdvertisementImpl является подтипом Advertisement (поскольку AdvertisementImpl расширяет Advertisement). Я опубликовал бумагу, в которой содержится руководство по дисперсии во многих языках. (например, Scala, C#, Java). слайды также доступны для быстрого обзора. Надеюсь это поможет.

person John Altidor    schedule 12.04.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]{}
person Andrzej Jozwik    schedule 05.03.2012
comment
Спасибо Ajozwik, реклама — это сущность JPA, а не черта. Репозиторий Crud — это интерфейс данных Spring. Знаете ли вы, как гарантировать, что только базовый класс Advertisement или его подклассы могут использоваться вместо любого класса, как здесь: var advertisementDAO: AdvertisementDAO[_] - person balteo; 06.03.2012
comment
Попробуйте var advertisementDAO: AdvertisementDAO[_ <:Advertisement] = _ - person Andrzej Jozwik; 06.03.2012