Scala(2.9.1)が初めてなので、List[Event]
があり、それをQueue[Event]
にコピーしたいが、次の構文はQueue[List[Event]]
代わりに:
val eventQueue = Queue(events)
何らかの理由で、次のように機能します:
val eventQueue = Queue(events : _*)
しかし、私はそれが何をするのか、そしてなぜそれが機能するのかを理解したいと思いますか?私はすでにQueue.apply
関数の署名を見ました:
def apply[A](elems: A*)
そして、最初の試みがうまくいかない理由を理解していますが、2番目の試みの意味は何ですか?この場合の:
および_*
とは何ですか。また、なぜapply
関数がIterable[A]
を受け取らないのですか?
a: A
はタイプの説明です。 Scalaでの型表記の目的は何ですか を参照してください
: _*
は、シーケンス型の単一の引数を可変引数シーケンス、つまりvarargsとして扱うようにコンパイラーに指示する、型表記の特別なインスタンスです。
シーケンスまたは反復可能な単一の要素を持つQueue.apply
を使用してQueue
を作成することは完全に有効であるため、単一のIterable[A]
を指定するとまさにこれが起こります。
これは、すべての要素を単一の引数としてではなく、独自の引数として渡すようコンパイラーに指示する特別な表記法です。 here を参照してください。
これはシーケンス引数を示す型注釈であり、言語仕様のセクション4.6.2の一般規則の「例外」として言及されています。 「繰り返しパラメータ」。
関数が可変数の引数を取る場合に便利です。 def sum(args: Int*)
などの関数は、sum(1)
、sum(1,2)
などとして呼び出すことができます。xs = List(1,2,3)
などのリストがある場合、 xs
ではなくList
であるため、Int
自体を渡すことはできませんが、sum(xs: _*)
を使用してその要素を渡すことができます。
Python人々:
Scalaの_*
演算子は、Pythonの *-operator とほぼ同等です。
例
Luigi Plinge が提供する link のscalaの例を変換)
def echo(args: String*) =
for (arg <- args) println(arg)
val arr = Array("What's", "up", "doc?")
echo(arr: _*)
to Pythonは次のようになります。
def echo(*args):
for arg in args:
print "%s" % arg
arr = ["What's", "up", "doc?"]
echo(*arr)
両方とも次の出力を提供します。
なに
アップ
doc?
違い:位置パラメータの展開
Pythonの*
- operatorは、固定引数関数の位置パラメータ/パラメータのアンパックも処理できます。
def multiply (x, y):
return x * y
operands = (2, 4)
multiply(*operands)
8
Scalaで同じことを行う:
def multiply(x:Int, y:Int) = {
x * y;
}
val operands = (2, 4)
multiply (operands : _*)
失敗します:
メソッドの乗算に十分な引数がありません:(x:Int、y:Int)Int。
未指定の値パラメーターy。
しかし、scalaでも同じことを実現できます。
def multiply(x:Int, y:Int) = {
x*y;
}
val operands = (2, 4)
multiply _ tupled operands
Lorrin Nelson によると、これがどのように機能するかです:
最初の部分f _は、引数が指定されていない部分的に適用された関数の構文です。これは、関数オブジェクトを保持するメカニズムとして機能します。 tupledは、単一のarity-n Tupleを取るarity-1の新しい関数を返します。
さらに読む: