스칼라 : 닐 vs리스트 ()


128

스칼라, 모든 사이에 어떤 차이가 Nil하고List() ?

그렇지 않다면 어느 것이 관용 스칼라 스타일입니까? 비어있는 새 목록을 만들고 비어있는 목록에서 패턴을 일치시킵니다.

답변:


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

무기한은 관용적이며 대부분의 경우에 바람직 할 수 있습니다. 질문이 있으십니까?


11
Nil더 관용적 이라고 말할 수 있습니다.
렉스 커

6
"eq"가 이미 말한 내용을 명확하게하기 위해 System.identityHashCode를 추가했습니다. 동일한 객체입니다.
James Iry

18
게다가 Nil은 객체를 직접 참조하는 반면 List ()는 메소드 호출입니다.
Jean-Philippe Pellet

6
아닌가 List[A]()(되지 NilfoldLeft위한 누산기 값 필요)? 예- 여기서 누산기로 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)
Raul

85

사용자 알 수 없음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)
                                               ^

나는 왜 2 :: Nil이 작동하지만 누산기를 접을 수 없는지 이해하지 못한다. y :: x
FUD

2
@FUD 글쎄, y :: x 작동 합니다. 문제는 반환되는 형식이 예상 한 형식이 아니라는 것입니다. List[Int]예상되는 유형이 List[Nothing]또는 Nil.type(나는 전자이지만 아마도 후자라고 생각 합니다 ) 동안을 반환합니다 .
Daniel C. Sobral

27

사용자 알 수 없음의 답변에서 알 수 있듯이 동일한 객체입니다.

관용적으로 Nil이 좋으며 짧기 때문에 선호됩니다. 그래도 예외가 있습니다 : 어떤 이유로 든 명시 적 유형이 필요한 경우

List[Foo]() 

보다 좋다

Nil : List[Foo]

36
도 있습니다 List.empty[Foo]세 번째 대안으로.
kassens
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.