เมื่อใดควรใช้เครื่องหมายเท่ากับในการประกาศเมธอด Scala


85

ด้วยเครื่องหมายเท่ากับ:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
  }
}

ไม่มีเครื่องหมายเท่ากับ:

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello!")
  }
}

ทั้งสองโปรแกรมข้างต้นดำเนินการในลักษณะเดียวกัน ในบล็อกโพสต์สิ่งที่ฉันไม่ชอบใน Scalaฉันอ่านว่าเมื่อเครื่องหมายเท่ากับหายไปเมธอดจะส่งคืนUnit(เหมือนกับของ Java void) ดังนั้นวิธีการที่ส่งคืนค่าจะต้องใช้เครื่องหมายเท่ากับ แต่วิธีการที่ไม่ส่งคืนค่าสามารถเขียนได้ด้วยวิธีใดวิธีหนึ่ง

แนวทางปฏิบัติที่ดีที่สุดในการใช้เครื่องหมายเท่ากับในเมธอด Scala ที่ไม่คืนค่าคืออะไร

คำตอบ:


109

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

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello!")
    123
  }
}

ไวยากรณ์ที่ไม่เท่ากันนั้นสั้นกว่าและอาจดู "สะอาดกว่า" แต่ฉันคิดว่ามันแค่เพิ่มความสับสน บางครั้งฉันลืมใส่เครื่องหมายเท่ากับและเชื่อว่าวิธีการของฉันส่งคืนค่าเมื่อมันส่งคืนหน่วยจริง เนื่องจากไวยากรณ์ประเภทที่ไม่เท่ากันและเท่ากับที่อนุมานมีความคล้ายคลึงกันทางสายตาจึงง่ายที่จะพลาดปัญหานี้

แม้ว่าฉันจะเสียค่าใช้จ่ายในการทำงานเพิ่มขึ้นเล็กน้อย แต่ฉันก็ชอบคำอธิบายประกอบประเภทที่ชัดเจนเมื่อมีความสำคัญ (กล่าวคืออินเทอร์เฟซแบบเปิดเผย)


1
ฉันชอบแนวทางนี้ชัดเจนกว่าและชัดเจนมากขึ้นสำหรับผู้อ่าน
Lukasz Korzybski

4
เห็นได้ชัดว่าตอนนี้เป็นรูปแบบที่แนะนำ ( docs.scala-lang.org/style/declarations.html#procedure_syntax ) ดังนั้นฉันจึงเปลี่ยนเป็นคำตอบที่ยอมรับ
Esko Luontola

1
ฉันเห็นด้วยเช่นกันฉันคิดว่าไวยากรณ์ที่ไม่มี = ควรถูกลบออกจากภาษาทั้งหมด
Ahmed Soliman Farghal

7
Martin Odersky ในคำปราศรัยของเขา "Scala with Style" กล่าวว่ามันเป็นความผิดพลาดครั้งประวัติศาสตร์ เขาต้องเพิ่มไวยากรณ์นี้ (โดยไม่มี =) เพื่อให้สามารถซ่อน "หน่วย" จากนักพัฒนา Java เพื่อไม่ให้สับสน นอกจากนี้เขายังกล่าวว่าจะถูกลบออกในอนาคต
tabdulradi

2
มีวิธีใดในการเตือนหากลืมเครื่องหมายเท่ากับในนิยามวิธีการ เป็นตัวเลือกคอมไพเลอร์เช่นหรือในเครื่องมือวิเคราะห์ซอร์สใด ๆ ?
VasiliNovikov

42

UPDATE: สำหรับ Scala-2.10 แนะนำให้ใช้เครื่องหมายเท่ากับ คำตอบเก่า:

วิธีการซึ่งผลตอบแทนที่Unitควรเสมอใช้การไม่เท่ากับไวยากรณ์ เพื่อหลีกเลี่ยงข้อผิดพลาดที่อาจเกิดขึ้นในการนำไปใช้งานใน API ตัวอย่างเช่นคุณอาจทำสิ่งนี้โดยไม่ได้ตั้งใจ:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
    123
  }
}

แน่นอนว่าเป็นตัวอย่างที่ไม่สำคัญ แต่คุณจะเห็นได้ว่าปัญหานี้อาจเกิดขึ้นได้อย่างไร เพราะการแสดงออกที่ผ่านมาไม่ได้กลับมาวิธีการของตัวเองจะมีผลตอบแทนประเภทอื่นที่ไม่ใช่Unit Unitสิ่งนี้เปิดเผยใน API สาธารณะและอาจก่อให้เกิดปัญหาอื่น ๆ ตามท้องถนน ด้วยการไม่เท่ากับไวยากรณ์ก็ไม่ได้ว่าสิ่งที่แสดงออกสุดท้ายคือ, Scala Unitแก้ไขประเภทกลับเป็น

นอกจากนี้ยังมีตัวละครสองตัวที่สะอาดกว่า :-) ฉันมักจะคิดว่าไวยากรณ์ที่ไม่เท่ากันทำให้โค้ดอ่านง่ายขึ้นเล็กน้อย เห็นได้ชัดว่าวิธีการที่เป็นปัญหาให้ผลตอบแทนUnitมากกว่าค่าที่เป็นประโยชน์บางอย่าง

ในบันทึกที่เกี่ยวข้องมีไวยากรณ์ที่คล้ายคลึงกันสำหรับวิธีนามธรรม:

trait Foo {
  def bar(s: String)
}

วิธีการที่มีลายเซ็นbar String=>UnitScala ทำสิ่งนี้เมื่อคุณไม่ใส่คำอธิบายประกอบประเภทในสมาชิกนามธรรม อีกครั้งนี่สะอาดกว่าและ (ฉันคิดว่า) อ่านง่ายขึ้น


3
การไม่ใช้เครื่องหมายเท่ากับยังเป็นคำแนะนำใน Scala Style Guide: davetron5000.github.com/scala-style/types/inference/…
Esko Luontola

6
ฉันเขียนบิตนั้นดังนั้นคุณควรจำไว้เมื่อคุณชั่งน้ำหนักอ้างอิง :-)
Daniel Spiewak

ฮ่า ๆ ดังนั้นฉันจึงอธิบายการแลกเปลี่ยนเล็ก ๆ น้อย ๆ นี้กับแฟนของฉันยกเว้นเนื่องจากการออกเสียง "บิต" ที่ไม่ดีของฉันออกมาเป็น "ผู้หญิงเลว" ไม่จำเป็นต้องพูดความตลกก็เกิดขึ้น
Saem

10
ScalaDays 2013, Martin Odersky, Keynote - Scala with Style ตอนที่ 45 : ควรหลีกเลี่ยงการประกาศโพรซีเดอร์ (ไวยากรณ์ที่ไม่เท่ากับ)
senia

4
คู่มือสไตล์อย่างเป็นทางการไม่แนะนำสิ่งนี้อีกต่อไป: docs.scala-lang.org/style/declarations.html#procedure_syntax
sbilstein

12

คุณต้องใช้การประกาศการเรียกลงชื่อเข้าใช้เท่ากับยกเว้นคำจำกัดความที่ส่งคืนหน่วย

ในกรณีหลังนี้คุณอาจละทิ้งเครื่องหมายเท่ากับ อย่างไรก็ตามไวยากรณ์นี้อาจเลิกใช้แล้วดังนั้นควรหลีกเลี่ยง การใช้เครื่องหมายเท่ากับและการประกาศประเภทการส่งคืนจะใช้ได้เสมอ


หนังสือรายชื่อผู้รับจดหมายซอร์สโค้ด อย่างไรก็ตามตั้งแต่นั้นเป็นต้นมาก็เห็นได้ชัดว่าไวยากรณ์หลังไม่น่าจะถูกเลิกใช้และเป็นที่ชื่นชอบของหลาย ๆ คน
Daniel C. Sobral

1
docs.scala-lang.org/style/types.html#function_valuesดูเหมือนว่าคำแนะนำสไตล์ types จะระบุว่าใช้ = ตลอดเวลา
BeepDog

4

สำหรับวิธีการScala Style Guideแนะนำให้ใช้ไวยากรณ์เท่ากับแทนที่จะเป็นไวยากรณ์ขั้นตอน

ไวยากรณ์ขั้นตอน

หลีกเลี่ยงไวยากรณ์ของโพรซีเดอร์เนื่องจากมีแนวโน้มที่จะสับสนเนื่องจากได้รับผลตอบแทนที่สั้นมาก

// don't do this
def printBar(bar: Baz) {
  println(bar)
}
// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}

0

สิ่งหนึ่ง: ลองนึกภาพคำสั่งสุดท้ายของวิธีการที่ควรส่งคืนหน่วยไม่ส่งคืนหน่วย การใช้ไวยากรณ์ที่ไม่เท่ากันนั้นสะดวกมากฉันหวังว่าสิ่งนี้จะไม่ถูกเลิกใช้เนื่องจากฉันเห็นกรณีการใช้งานหลายอย่าง


0

เมื่อเวลาผ่านไปรูปแบบเริ่มต้นได้เปลี่ยนไปและมีการกล่าวถึงสิ่งนี้ในหลายความคิดเห็นเกี่ยวกับคำตอบขอแนะนำในคู่มือสไตล์อย่างเป็นทางการเพื่อใช้=ไวยากรณ์สำหรับการประกาศฟังก์ชัน


1
ลิงก์ที่คุณให้ไว้จะพูดถึงฟังก์ชันเท่านั้นไม่ใช่โพรซีเดอร์ (เช่นฟังก์ชันที่ส่งคืนหน่วย)
Esko Luontola

คุณพูดถูก @EskoLuontola ขออภัยที่ฉันอาจคัดลอกลิงค์ผิดจากหนึ่งในหลายแท็บที่ฉันเปิดมันได้รับการอัปเดตแล้ว
BeepDog

0

สำหรับเมธอดที่ไม่มีค่าส่งคืนวิธีการแสดงวิธีการดังกล่าวคือการละเว้นประเภทผลลัพธ์และเครื่องหมายเท่ากับตามวิธีการที่มีบล็อกที่อยู่ในวงเล็บปีกกา ในรูปแบบนี้วิธีการนี้ดูเหมือนขั้นตอนวิธีการที่ดำเนินการเพื่อผลข้างเคียงเท่านั้น

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