You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 07:27:23