4

基になるケース クラスを作成する apply メソッドが定義されたファクトリ オブジェクトを作成したい - サンプル コードは次のとおりです。

object DeptEntry {  
  def apply(url: String, fullName: String, address: String, city: String): DeptEntry = {
    new DeptEntry(url.toLowerCase, fullName.toLowerCase, address.toLowerCase, city.toLowerCase)
  }
}

case class DeptEntry private(url: String, fullName: String, address: String, city: String) {
}

問題は、オブジェクトとケース クラスのコンストラクターの apply メソッドが同じパラメーター リストを持っていることです。だからコンパイラは私にこのエラーを与えます:

method apply is defined twice
  conflicting symbols both originated in file 'DeptEntry.scala'
case class DeptEntry private(url: String, fullName: String,
       ^

この問題の回避策はありますか?

どうもありがとう

4

4 に答える 4

3

ケースクラスを宣言するabstract

object DeptEntry {  
  def apply(url: String, fullName: String, address: String, city: String): DeptEntry = {
    new DeptEntry(url.toLowerCase, fullName.toLowerCase, address.toLowerCase, city.toLowerCase) {}
  }
}

abstract case class DeptEntry private(url: String, fullName: String, address: String, city: String) {
}

これは、SI-844 に関するIulian Dragos のコメントによるものです。

于 2014-08-04T08:56:55.650 に答える
1

を作成するcase classと、Scala コンパイラは apply メソッドを使用してコンパニオン オブジェクトを自動的に生成します。この apply メソッドには、case クラスのコンストラクターと同じパラメーターがあります。これが、このコンパイラ エラーが発生する理由です。上書きできないという事実により、次のようなものが確実に保持されます。

val inputUrl = "MyUrl://blabla"
val DeptEntry(outputUrl, _, _, _) = DeptEntry(inputUrl, "", "", "")
outputUrl == inputUrl 

クラス定義から を削除してcase、コンパニオン オブジェクトapply(およびunapply抽出が必要な場合) を自分で (必要toStringに応じequalshashCodeクラス自体に) 記述してみてください。

于 2013-07-04T09:19:27.973 に答える
0

1 つの可能性は、ユーザーからクラスを (少し) 隠すことです。

sealed trait DeptEntry
object DeptEntry {
  def apply(url: String, fullName: String,
            address: String, city: String): DeptEntry = // ...

  case class Value protected[DeptEntry](
    url: String, fullName: String, address: String, city: String
  )
}

この方法では競合が発生せず、必要にDeptEntry.Value応じてパターン マッチを有効にすることができます。このソリューションが便利かどうかは、ユースケースによって異なります。特性に適切なvals が必要な場合は、次のように宣言できます。

sealed trait DeptEntry {
    val url: String
    val fullName: String
    val address: String
    val city: String
}

のフィールドはcase classそれらを上書きします。

于 2013-07-04T11:36:57.257 に答える
0

DeptEntry を「通常の」(ケース クラスではない) クラスにすることができます。または、オブジェクトで別の名前のメソッドを使用できます。(例: DeptEntry.lowerCase(...))

于 2013-07-04T09:19:19.830 に答える