6

次のような入力があります"1 2 3 4 5"

私がやりたいことは、一連の新しい変数を作成することですa。シーケンスの最初の変数、 b2 番目の変数、xs残りの変数をシーケンスとして作成します (明らかに、3 つの異なる行で実行できますが、複数の代入を使用します)。

少し検索すると、使用できた右無視シーケンス パターンが見つかりました。

val Array(a, b, xs @ _*) = "1 2 3 4 5".split(" ")

私が理解していないのは、タプルで試してもうまくいかないのはなぜですか? これに対してエラーが発生します:

val (a, b, xs @ _*) = "1 2 3 4 5".split(" ")

エラーメッセージは次のとおりです。

<console>:1: error: illegal start of simple pattern

を使用せずに複数の割り当ての代替手段はありますArrayか?

数日前に Scala を使い始めたばかりなので、ご容赦ください :-) よろしくお願いします!

4

5 に答える 5

18

他の回答は、タプルを使用できない理由を教えてくれますが、配列はこの目的には扱いにくいです。私はリストを好む:

val a :: b :: xs = "1 2 3 4 5".split(" ").toList
于 2012-04-24T18:02:19.167 に答える
12

簡単な答え

val Array(a, b, xs @ _*) = "1 2 3 4 5".split(" ")

ここに表示されている構文は、単純なパターン マッチです。"1 2 3 4 5".split(" ")次のように評価されるため、機能しArrayます。

scala> "1 2 3 4 5".split(" ")
res0: Array[java.lang.String] = Array(1, 2, 3, 4, 5)

右側が であるためArray、左側のサイズのパターンもArray

右側のサイズもタプルに評価される場合にのみ、左側をタプルにすることができます。

val (a, b, xs) = (1, 2, Seq(3,4,5))

より複雑な答え

ここで技術的に何が起こっているかというと、パターン マッチ構文がオブジェクトのunapplyメソッドを呼び出しているというArrayことです。これは次のようになります。

def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] =
  if (x == null) None else Some(x.toIndexedSeq)

このメソッドは を受け入れることに注意してくださいArray。これは、割り当ての右側のサイズで Scala が見なければならないものです。そして、使用した構文Seqを許可する を返します。@_*

Tuple3がではなくをパラメータとしてunapplySeq定義されているため、タプルを使用したバージョンは機能しません。Product3Array

def unapply[T1, T2, T3](x: Product3[T1, T2, T3]): Option[Product3[T1, T2, T3]] =
  Some(x)

unapplyオブジェクトを作成してorunapplySeqメソッドを記述するだけで、実際にはこのような「エクストラクタ」を実行できます。

于 2012-04-24T17:47:41.980 に答える
7

答えは次のとおりです。

val a :: b :: c = "1 2 3 4 5".split(" ").toList

場合によっては、一致しない要素を無視して、リストの最初の n 要素だけをバインドしたい場合があることを明確にする必要があります。これを行うには、末尾にアンダースコアを追加するだけです:

val a :: b :: c :: _ = "1 2 3 4 5".split(" ").toList

その方法:

c = "3" vs. c = List("3","4","5")
于 2012-04-24T18:02:53.747 に答える
2

私は決して Scala の専門家ではありませんが、これは、Scala のタプルが Tuple2 から Tuple22 までのクラスのシンタティック シュガーにすぎないという事実に関係しているのではないかと思います。

つまり、Scala のタプルは、Python や他の同種の言語のような柔軟な構造ではないため、先験的なサイズが不明なタプルを実際に作成することはできません。

于 2012-04-24T17:47:43.483 に答える