1

ケースクラスは関数として渡すことができますが、通常のクラスを同じ方法で関数として渡すにはどうすればよいですか?

case class Fraction(val num: Int, val den: Int)

object Run extends App {
    def doFraction(in: (Int, Int) => Fraction) {}

    doFraction(Fraction)
}   

上記のコードは機能しますが、以下のコードを変更して同じ効果を得るにはどうすればよいですか?

class Fraction(val num: Int, val den: Int) {
    /* what can I put here or in companion object to make this compile? */
}

object Fraction {
    /* ... */
}

object Run extends App {
    def doFraction(in: (Int, Int) => Fraction) {}

    doFraction(Fraction)
}   
4

2 に答える 2

8

コンパニオン オブジェクトは Function トレイトを拡張し、 apply() メソッドを定義する必要があります。

// object Fraction extends Function2[Int, Int, Fraction]
object Fraction extends ((Int, Int) => Fraction) {
  def apply(num: Int, den: Int) = new Fraction(num, den)
}
于 2013-10-22T16:55:57.950 に答える
0

いずれの場合も、対応する apply メソッド (apply(Int, Int): Fraction の場合) を実装する必要があります。オブジェクト Fraction で継承が必要ない場合 (Lex が言ったように)、次のコードも機能します。

doFraction(Fraction.apply _)

Fraction.apply _ Fraction.apply メソッドを型 (Int, Int) => Fraction の関数に変換します

ケース クラスに関しては、生成されたバイトコードを調べると、コンパニオン オブジェクトの生成されたクラスが既に (Int, Int) => Fraction を拡張していることがわかります。まだいくつかのニュアンスがあります - 詳細についてはこれを見てください: https://groups.google.com/forum/#!msg/scala-user/ZhSDMJgwghc/DZpbzvVYHXIJ

于 2013-10-22T18:11:35.740 に答える