3

これが基本的な例です。既存のシーケンスを使用するか、複数のパラメーターを使用するかの2つの異なる方法でクラスを初期化する機能が必要であることをscalaに認識させることができません。

私が受け取るエラーは次のとおりです。

二重定義:メソッドapply:(params:Int *)chorle.scala.tests.MultiParamとメソッドapply:(pList:
Seq [Int])chorle.scala.tests.9行目のMultiParamは、消去後に同じタイプになります:(params: Seq)chorle.scala.tests.MultiParam

どちらがいいですか、ここで何が起こっているのかわかります-コンパイル後、両方の関数が同じヘッダー署名になります。ただし、実際には同じようには機能しません。apply(Seq)バージョンしかない場合は、apply(1,2,3)を呼び出すことはできません。apply(seq)を呼び出すことはできません。逆に。実際の関数呼び出しにパッチを適用するさまざまな方法を知っていますが、これに適切に対処し、クラスで1回だけ行うにはどうすればよいですか?ありがとうございました!

class MultiParam protected (pList:Seq[Int]) 

object MultiParam {
  def apply(pList:Seq[Int]): MultiParam = new MultiParam(pList)
  def apply(params: Int *): MultiParam = new MultiParam(params)


} 
4

2 に答える 2

5

問題は、いわゆる「繰り返しパラメーター」形式が、定義サイトと特別な種類の呼び出しサイトの両方で構文糖衣でありIndexedSeq、あいまいさにつながるという事実に由来します。

これを処理する標準的な方法があり、標準コレクション ライブラリのさまざまな場所にあります。

package rrs.scribble

object MP {
  class MultiParam protected (pList:Seq[Int]) {
    override def toString: String = pList.mkString("[[", ", ", "]]")
  }

  object MultiParam {
    def apply(): MultiParam = new MP.MultiParam(List.empty[Int])
    def apply(ints: Seq[Int]): MultiParam = new MP.MultiParam(ints)
    def apply(i1: Int, iMore: Int*): MultiParam = new MP.MultiParam(i1 +: iMore)
  }
}

REPL では:

scala> MultiParam()
res0: rrs.scribble.MP.MultiParam = [[]]

scala> MultiParam(12)
res3: rrs.scribble.MP.MultiParam = [[12]]

scala> MultiParam(12, 34)
res4: rrs.scribble.MP.MultiParam = [[12, 34]]

scala> MultiParam(12, 34, 56)
res5: rrs.scribble.MP.MultiParam = [[12, 34, 56]]
于 2013-02-05T03:14:15.397 に答える
4

両方のメソッドを生成する方法がないため、そのままでは使用できません。それを回避する唯一の方法は、それらを明確にすることです。

object MultiParam {
  def apply(pList:Seq[Int]): MultiParam = new MultiParam(pList)
  def apply(param: Int, params: Int *): MultiParam = new MultiParam(param +: params)
  def apply(): MultiParam = new MultiParam(Nil)
} 
于 2013-02-05T03:08:37.707 に答える