0

これがバグなのか、Scala を十分に理解していないのかはわかりません。今日、いくつかのリスト関数を使って REPL で遊んでいました。これが私がしたことです:

まず、リストを作成しました。

scala> val myList = List(1.0, 2.0, 3.0)
myList: List[Double] = List(1.0, 2.0, 3.0)

次に、別の double を先頭に追加して、別のリストを作成しました。

scala> val newMyList = 4.0 :: myList
newMyList: List[Double] = List(4.0, 1.0, 2.0, 3.0)

ここで、newMyList で productArity (List.productArity) を要求すると、次のようになります。

scala> print(newMyList.productArity)
2

最初のリストを他のリストとは異なる方法で扱っているようです。これは意図した動作ですか、それともバグですか?

scala> print(newMyList.productElement(0))
4.0
scala> print(newMyList.productElement(1))
List(1.0, 2.0, 3.0)

0、1 より大きい要素にアクセスしようとすると、java.lang.IndexOutOfBoundsException が発生することに注意してください。2 は 2.0 を返し、3 は 3.0 を返す必要がありますよね?

4

2 に答える 2

5

Scalaの AListは、LISP 言語で使用されるリストに似たコンスセル ベースの構造です。これは、それぞれが head 要素と tail 要素を持つセルで構成され、最後のセルには の tail 要素がありNilます。

Scala の空のセルはNilで、空でないセルは::(別名 "Cons") です。リストのこれら 2 つの具体的なサブタイプは、参照先のProduct特性を提供するケース クラスとして実装されます。

だから代わりに

List(1.0, 2.0, 3.0)

あなたが考えることができます

::(1.0, ::(2.0, ::(3.0, Nil)))

またはグラフィカルに説明

Cons(1.0, .)
          Cons(2.0, .)
                    Cons(3.0, .)
                              Nil

A::はアリティ 2 の積で、最初の要素は頭、2 番目の要素は尾です。そのため、2 番目のリストの 2 つの製品要素として と を取得します4List(1, 2, 3)

リストの要素にアクセスするには、apply代わりに を使用します。リストのサイズは で与えられsizeます:

List(4.0, 1.0, 2.0, 3.0).apply(2) // -> 2.0
List(4.0, 1.0, 2.0, 3.0).size     // -> 4
于 2014-05-10T15:48:46.293 に答える
2

List-Nilとには 2 つのケースが考えられ::ます。

::次のように定義されています。

case class ::[A](val head: A, val tail: List[A]) extends List[A]

リストの先頭と末尾の 2 つの要素を持つ製品です。

productArityを呼び出しているため、空でないリストが 2 を返すのはこのためです::.productArity

対照的に、Nil.productArity0 を返します。

newMyList.productElement(0)から最初の要素を取得しているため、リストの先頭であり、リスト::newMyList.productElement(1)末尾です。インスタンスの要素はこれ以上ないConsため、1 より大きいインデックスは範囲外です。

リスト自体にインデックスを付けたい場合は、次のapplyメソッドを使用できます。

print(newMyList(2))
于 2014-05-10T15:47:31.937 に答える