สกาล่า: ไม่มี vs รายการ ()


128

ใน Scala จะมีความแตกต่างใด ๆ ระหว่าง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เป็นสำนวนมากกว่า
Rex Kerr

6
เพิ่ม System.identityHashCode เพื่อชี้แจงสิ่งที่ "eq" พูดแล้ว - เป็นวัตถุเดียวกัน
James Iry

18
นอกจากนี้ Nil ยังอ้างอิงวัตถุโดยตรงในขณะที่ List () เป็นการเรียกใช้เมธอด
Jean-Philippe Pellet

6
ไม่จำเป็นList[A]()(ไม่Nil) เป็นค่าตัวสะสมสำหรับ foldLeft? ตัวอย่าง - scala> Map(1 -> "hello", 2 -> "world").foldLeft(List[String]())( (acc, el) => acc :+ el._2) res1: List[String] = List(hello, world)การใช้Nilเป็นตัวสะสมที่นี่จะไม่ทำงาน
Kevin Meredith

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

ตามที่ผู้ใช้ไม่ทราบคำตอบแสดงว่าเป็นวัตถุเดียวกัน

สำนวนควรเป็นที่ต้องการเพราะเป็นเรื่องที่ดีและสั้น แม้ว่าจะมีข้อยกเว้น: หากต้องการประเภทที่ชัดเจนไม่ว่าด้วยเหตุผลใดก็ตามที่ฉันคิด

List[Foo]() 

ดีกว่า

Nil : List[Foo]

36
นอกจากนี้ยังList.empty[Foo]มีทางเลือกที่สาม
kassens
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.