ใน Scala จะมีความแตกต่างใด ๆ ระหว่างNil
และList()
?
ถ้าไม่สไตล์ Scala สำนวนไหนมากกว่ากัน? ทั้งสำหรับการสร้างรายการว่างใหม่และการจับคู่รูปแบบในรายการว่าง
ใน Scala จะมีความแตกต่างใด ๆ ระหว่างNil
และList()
?
ถ้าไม่สไตล์ Scala สำนวนไหนมากกว่ากัน? ทั้งสำหรับการสร้างรายการว่างใหม่และการจับคู่รูปแบบในรายการว่าง
คำตอบ:
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 เป็นสำนวนมากกว่าและเป็นที่ต้องการในกรณีส่วนใหญ่ คำถาม?
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
เป็นตัวสะสมที่นี่จะไม่ทำงาน
Map(1 -> "hello", 2 -> "world").foldLeft(Nil: List[String])( _ :+ _._2)
ไม่ทราบผู้ใช้แสดงว่าค่ารันไทม์ของทั้งสอง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)
^
y :: x
ไม่ได้ผล ปัญหาคือประเภทที่ส่งคืนไม่ใช่ประเภทที่คาดไว้ มันจะส่งคืนList[Int]
ในขณะที่ประเภทที่คาดไว้คือList[Nothing]
หรือNil.type
(ฉันคิดว่าแบบเดิม แต่อาจจะเป็นแบบหลัง)
ตามที่ผู้ใช้ไม่ทราบคำตอบแสดงว่าเป็นวัตถุเดียวกัน
สำนวนควรเป็นที่ต้องการเพราะเป็นเรื่องที่ดีและสั้น แม้ว่าจะมีข้อยกเว้น: หากต้องการประเภทที่ชัดเจนไม่ว่าด้วยเหตุผลใดก็ตามที่ฉันคิด
List[Foo]()
ดีกว่า
Nil : List[Foo]
List.empty[Foo]
มีทางเลือกที่สาม
Nil
เป็นสำนวนมากกว่า