1

ケースクラスを使用してスマートコンストラクターを実装しようとしています。copyメソッドをうまくオーバーライドすることapplyができたので、コンパニオン オブジェクトの でうまくいったはずですが、 を渡そうとしたときに壁にぶつかりましたBigInt。入れてみましdef apply(value: BigInt): Option[Natural]たが、scalacシンボルの競合について不平を言います。

import spire.math.Integral // companion object contains implicit Integral[BigInt]

case class Natural private (value: BigInt) {
  def copy(value: BigInt = this.value): Option[Natural] =
    Natural.apply(value)
}

object Natural {
  def apply[A](x: A)(implicit A: Integral[A]): Option[Natural] =
    if (A.isPositive(x)) Some(Natural(x))
    else None
}

/** In Foo.scala */
Natural(5L) // Option[Natural] = Some(Natural(5))
Natural(BigInt(5L)) // constructor Natural in class Natural cannot be accessed in object Foo

そんなことはありえないのではないでしょうか?

4

2 に答える 2

2

発生しているエラーは、メソッドのオーバーロードが原因だと思います。ケース クラスを作成するとき、コンパイラは次のシグネチャを生成します。

def apply(x: T): T 

コンパニオン オブジェクト T のケース クラス T の場合。そのため、メソッドを呼び出すとき、メソッド選択は最も具体的なシグネチャを最初に選択します。Natural.apply(x: T): Tコンパニオンオブジェクトで推移的に非公開とマークされている危険性があるものを呼び出そうとします。apply(x: T): Tを生成し、 も定義しているため、競合するシンボルが問題になりますapply(x: T): T

あなたの最善の策は、プレーンな Scala クラスを使用し、抽出パターン、ハッシュ、等価性などを手動で実装することです。

于 2013-10-19T05:34:26.703 に答える