Scala:如何在Trait中通过类型使用Object?Model-Row实现遇错
Scala 实现类似 Rails ActiveRecord 的 Model-Row 结构问题
问题代码
trait Model[A]: def query = "model has this good stuff I want to use in RowData" trait RowData[B <: Model[B]]: def query = B.query case class Person(name: String, age: Int) extends RowData[Person] object Person extends Model[Person] Person("onur", 38).query // 期望能正常调用
错误说明
上述代码中,RowData trait 内出现「Not found: B」错误,原以为Model[A]作为单例对象可直接通过类型参数B调用其方法,实际无法实现。
解决思路与修正代码
Scala中类型参数B代表的是类型(比如Person类),而非继承了Model的单例对象,因此不能直接通过B.query访问单例的方法。需要让RowData的实例能关联到对应的Model单例对象,以下是两种可行方案:
方案一:在RowData中定义抽象方法获取Model实例
trait Model[A]: def query = "model has this good stuff I want to use in RowData" trait RowData[B]: // 定义抽象方法,让子类实现以返回对应的Model单例 def model: Model[B] def query = model.query case class Person(name: String, age: Int) extends RowData[Person]: // 实现model方法,指向Person单例对象 override def model: Model[Person] = Person object Person extends Model[Person] // 现在可正常调用 Person("onur", 38).query
方案二:使用上下文绑定(隐式传递Model实例)
trait Model[A]: def query = "model has this good stuff I want to use in RowData" // 使用using子句隐式注入Model实例 trait RowData[B](using val model: Model[B]): def query = model.query case class Person(name: String, age: Int) extends RowData[Person] object Person extends Model[Person] // 调用时,Person单例作为隐式值自动传入,可正常执行 Person("onur", 38).query
核心原因
原代码混淆了类型与单例对象的概念:RowData的类型参数B是Person类的类型,而继承Model的是Person单例对象(object Person),二者并非同一概念,因此无法直接通过B.query访问单例的方法。必须通过显式引用或隐式传递的方式,让RowData实例获取到对应的Model单例对象。
内容的提问来源于stack exchange,提问作者Onur Eren Elibol
相关产品推荐
相关产品推荐

