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`

ケースクラスを機能させるブードゥー教と関係があると思います。

私がやろうとしていることをすることは可能ですか?

更新:さらに検討すると、これはケースクラスの継承の禁止と関係があると思います。しかし、ここではケース クラス マジックが本当に必要です。生成されたapplyメソッドunapplyと ScalaQuery マッピングに依存しています。

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

が欠落しているため、例は機能しませんnewAccount(id, name)実際に呼び出すAccount.apply(id, name)と、呼び出すことができない が返さAccountれますwith。で拡張さnew Account(id, name) with BalanceTotalれる無名クラスに変換されます。コードが機能しない理由を理解するのに役立つことを願っています。AccountBalanceTotal

于 2012-05-04T16:01:37.640 に答える
1

あなたの問題は for ではなく、yield です。次のようにブラケットを使用すると、機能します。

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