1

我有一个看起来像这样的域模型:

case class Account(id: Int, name: String)

trait BalanceTotal {
  def balance: BigDecimal
}

我的目标是拥有一个简单、轻量级的Account案例类,然后是一个Account with BalanceTotal仅在进行余额计算的方法内创建的增强类(这很昂贵)。

使用这种结构,我可以静态地确保当我只有一个轻量级对象时,我永远不会指望存在平衡。我当然知道Option,但我希望类型检查器阻止代码在我需要平衡丰富对象的地方使用轻量级对象,反之亦然,我认为这不会Option给我。

无论如何,我想做的是:

for{ Account(id,name) <- accounts } {
  yield Account(id, name) with BalanceTotal {
    override val balance = BigDecimal(44)
  }
}

但这失败了:

';' expected but 'with' found

如果我尝试使用new Account而不是Account,我得到:

super constructor arguments cannot reference unconstructed `this`

我认为这与使案例类起作用的巫术有关。

有可能做我想做的事吗?

更新:进一步考虑,我想这与禁止案例类继承有关。但我确实需要这里的案例类魔法:我的 ScalaQuery 映射依赖于生成的applyunapply方法。

4

3 回答 3

2

它对我来说没问题:

>scala
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.
7.0).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

case class Account(id: Int, name: String)

trait BalanceTotal {
  def balance: BigDecimal
}
val enrichedAccount = new Account(1, "foo") with BalanceTotal {
  override val balance = BigDecimal(44)
}

// Exiting paste mode, now interpreting.

defined class Account
defined trait BalanceTotal
enrichedAccount: Account with BalanceTotal = Account(1,foo)
于 2012-05-04T15:40:59.703 回答
1

您的示例由于缺少new. Account(id, name)实际调用Account.apply(id, name)并且返回一个Account你不能调用的with. new Account(id, name) with BalanceTotal被翻译成一个匿名类,扩展Account名为BalanceTotal. 希望这有助于理解为什么您的代码不起作用。

于 2012-05-04T16:01:37.640 回答
1

你的问题不在于结果,而在于产量。使用如下括号,它将起作用:

for ( Acount(id, name) <- accounts) yield 
  (new Account(id, name) with BalanceTotal { 
    override val balance = BigDecimal(42) 
  })
于 2012-05-05T15:11:20.203 回答