Еще одна ошибка несоответствия типов scala - PullRequest
4 голосов
/ 06 марта 2012

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

// Model object base class
abstract class Model[M <: Model[M]] {

  val dao: Dao[M]
}

// DAO for each model object, with find, delete, update
abstract class Dao[M <: Model[M]] {

  // meta data describing the model object
  case class Column(val name:String, val get: M => _)

  val columns : Map[String,Column]
}

Вот конкретное использование как модели, так и связанной с ней DAO.

// example simple model object with it's DAO 
case class ItemModel (val name:String) extends Model[ItemModel] {
  val dao = ItemDao
}

object ItemDao extends Dao[ItemModel] {

  val columns = Map("name" -> Column("name", { v:ItemModel => v.name}))
}

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

object Works {

  // normal access pattern
  def good1(value: ItemModel) = value.name

  // even through the DAO
  def good2(value: ItemModel) = value.dao.columns("name").get(value)
}

Проблема в том, что я пытаюсь получить общий доступ к объекту. Я не могу получить сигнатуру метода для передачи значений Model без жалоб компилятора.

// Trouble trying to manipulate base model objects
object Trouble {

  // type mismatch;  found   : value.type (with underlying type test.Model[_])  required: _$2 where type _$2 Test.scala   
  def bad1(value: Model[_]) = value.dao.columns("name").get(value)  

  // type mismatch;  found   : value.type (with underlying type test.Model[_ <: test.Model[_]])  required: _$3 where type _$3 <: test.Model[_]
  def bad2(value: Model[_ <: Model[_]]) = value.dao.columns("name").get(value)

  // type mismatch;  found   : value.type (with underlying type X forSome { type X <: models.Model[X] })  required: X where type X <: models.Model[X]
  def bad3(value: X forSome {type X <: Model[X]}) = value.dao.columns("name").get(value)
}

Любая помощь или указатели будут с благодарностью.

1 Ответ

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

Во всех ваших плохих подпрограммах значение имеет тип Model, но get из Column ожидает M.Вы можете сделать:

def good[M <: Model[M]](value: M) = value.dao.columns("name").get(value)

Избегайте экзистенциальных типов, когда они вам не нужны, они усложняют ситуацию.Кроме того, ваш Column.get также может быть M => Any;с ковариацией это не налагает никаких ограничений на то, какие функции разрешены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...