Scala:NilとList()


128

スカラ座では、間のすべてのいずれかの違いがあるNilとはList()

そうでない場合、どちらがより慣用的なScalaスタイルですか?新しい空のリストの作成と空のリストでのパターンマッチングの両方。

回答:


188
scala> println (Nil == List())
true

scala> println (Nil eq List())
true

scala> println (Nil equals List())
true

scala> System.identityHashCode(Nil)
374527572

scala> System.identityHashCode(List())
374527572

Nilはより慣用的であり、ほとんどの場合に優先できます。質問?


11
あなたはそれNilがより慣用的であると言うことができます。
レックスカー

6
「eq」がすでに言っていることを明確にするためにSystem.identityHashCodeを追加しました-それらは同じオブジェクトです。
James Iry、

18
さらに、Nilはオブジェクトを直接参照しますが、List()はメソッド呼び出しです。
Jean-Philippe Pellet

6
foldLeftのアキュムレータ値としてList[A]()(ではないNil)必要はありませんか?例- ここでアキュムレータとしてscala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world)使用Nilしても機能しません。
ケビンメレディス

6
Map(1 -> "hello", 2 -> "world").foldLeft(Nil: List[String])( _ :+ _._2)
ラウル

84

ユーザー未知のは、両方の実行時の値を示しているNilList()同じです。ただし、それらの静的タイプは以下ではありません。

scala> val x = List()
x: List[Nothing] = List()

scala> val y = Nil
y: scala.collection.immutable.Nil.type = List()

scala> def cmpTypes[A, B](a: A, b: B)(implicit ev: A =:= B = null) = if (ev eq null) false else true
cmpTypes: [A, B](a: A, b: B)(implicit ev: =:=[A,B])Boolean

scala> cmpTypes(x, y)
res0: Boolean = false

scala> cmpTypes(x, x)
res1: Boolean = true

scala> cmpTypes(y, y)
res2: Boolean = true

これは、フォールドのアキュムレータなど、タイプを推論するために使用される場合に特に重要です。

scala> List(1, 2, 3).foldLeft(List[Int]())((x, y) => y :: x)
res6: List[Int] = List(3, 2, 1)

scala> List(1, 2, 3).foldLeft(Nil)((x, y) => y :: x)
<console>:10: error: type mismatch;
 found   : List[Int]
 required: scala.collection.immutable.Nil.type
       List(1, 2, 3).foldLeft(Nil)((x, y) => y :: x)
                                               ^

2 :: Nilは機能するがフォールドのアキュムレータが機能しない理由がわかりませんy :: x
FUD

2
@FUDまあ、y :: x 動作します。問題は、それが返す型が期待される型ではないことです。それは返すList[Int]型が期待される一方でいずれかである、List[Nothing]またはNil.type(私はかつて、多分後者だと思います)。
ダニエルC.ソブラル2013年

27

未知のユーザーの答えが示すように、それらは同じオブジェクトです。

素晴らしくて短いので、慣用的にはNilをお勧めします。ただし例外があります。何らかの理由で明示的な型が必要な場合

List[Foo]() 

より良い

Nil : List[Foo]

36
List.empty[Foo]3番目の選択肢もあります。
カッセン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.