Скала: ноль против списка ()

97

В Scala, существует ли какая-либо разница между Nil и List()?

Если нет, то какой более идиоматический стиль Scala? И для создания новых пустых списков и сопоставления шаблонов в пустых списках.

Теги:

3 ответа

144
Лучший ответ
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

Нил более идиоматичен и может быть предпочтительнее в большинстве случаев. Вопросы?

  • 8
    Вы могли бы упомянуть, что Nil более идиоматичен.
  • 0
    Они оба каждый раз создают новый объект? Это имеет значение?
Показать ещё 9 комментариев
79

Пользователь неизвестен показал, что значение времени выполнения как Nil, так и List() одинаково. Однако их статический тип не таков:

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)
                                               ^
  • 0
    я не понимаю, почему 2 :: Nil работает, но не скинуть аккумулятор y :: x
  • 1
    @FUD Ну, y :: x работает. Проблема в том, что возвращаемый тип не является ожидаемым типом. Он возвращает List[Int] , в то время как ожидаемый тип - List[Nothing] или Nil.type (я думаю, что первый, но, возможно, второй).
21

Как показывает пользовательский ответ, они являются одним и тем же объектом.

Идиоматически Нил должен быть предпочтительнее, потому что он приятный и короткий. Там исключение: если явный тип нужен по любой причине, я думаю,

List[Foo]() 

лучше, чем

Nil : List[Foo]
  • 31
    Также существует List.empty[Foo] в качестве третьей альтернативы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню