ทำไมหลายภาษาไม่สนับสนุนพารามิเตอร์ที่มีชื่อ [ปิด]


14

ฉันแค่คิดว่าจะอ่านรหัสได้ง่ายขึ้นแค่ไหนเมื่อเรียกฟังก์ชั่นคุณสามารถเขียน:

doFunction(param1=something, param2=somethingElse);

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

มีข้อเสียที่ฉันหายไปนี้หรือไม่? ถ้าไม่ทำไมหลายภาษาไม่อนุญาตสิ่งนี้


1
คุณสามารถให้ภาษาที่ควร (และสามารถ) ตั้งชื่อพารามิเตอร์ แต่ไม่มีหรือไม่
ไบรอันเฉิน

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

2
@SteveFallows: "Named Parameter Idiom" ดูเหมือนจะเป็นชื่อแปลก ๆ สำหรับคำจำกัดความของ API ที่คล่องแคล่ว (ตามชื่อโดย Martin Fowler) ในคลาสตัวสร้าง คุณสามารถค้นหาตัวอย่างของรูปแบบเดียวกันในหนึ่งในรายการแรกของโจชัวโบลชมีผลบังคับใช้ Java
jhominal

3
นี่ไม่ใช่คำถามตามความคิดเห็น
Catskul

2
ตกลง "ทำไมหลายภาษาไม่รองรับพารามิเตอร์ที่มีชื่อ" เป็นคำถามเกี่ยวกับประวัติศาสตร์ของภาษามากกว่าความคิดเห็น มันจะเป็นความเห็นถ้ามีคนถามว่า "พารามิเตอร์ไม่ได้ตั้งชื่อดีกว่าหรือไม่"
Andy Fleming

คำตอบ:


14

การระบุชื่อพารามิเตอร์ไม่ได้ทำให้โค้ดอ่านง่ายขึ้นเสมอไป: เป็นตัวอย่างคุณต้องการอ่านmin(first=0, second=1)หรือmin(0, 1)ไม่?

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

ฉันคิดอย่างน้อยสองเหตุผล:

  • โดยทั่วไปการแนะนำไวยากรณ์ที่สองสำหรับความต้องการที่มีอยู่แล้ว (ที่นี่การผ่านพารามิเตอร์) เป็นสิ่งที่ประโยชน์จะต้องมีความสมดุลกับค่าใช้จ่ายโดยธรรมชาติของความซับซ้อนของภาษาที่แนะนำ (ทั้งในการใช้ภาษาและโมเดลความคิดของโปรแกรมเมอร์) ;
  • มันทำให้การเปลี่ยนชื่อพารามิเตอร์เป็นการเปลี่ยนแปลงการแตกหักของ API ซึ่งอาจไม่สอดคล้องกับความคาดหวังของนักพัฒนาที่การเปลี่ยนชื่อพารามิเตอร์เป็นการเปลี่ยนแปลงเล็กน้อยและไม่ทำลาย

โปรดทราบว่าผมไม่ทราบว่าภาษาใด ๆ ที่ดำเนินการตั้งชื่อพารามิเตอร์โดยไม่ได้ดำเนินการตามพารามิเตอร์ที่ไม่จำเป็น (ซึ่งต้องใช้ชื่อพารามิเตอร์) - ดังนั้นคุณควรจะระมัดระวังในการไขว้เขวประโยชน์การอ่านของพวกเขาซึ่งสามารถรับได้มากขึ้นอย่างต่อเนื่องกับความหมายของFluent การเชื่อมต่อ


6
ฉันเขียนโค้ดเป็นประจำในหลาย ๆ ภาษาฉันมักจะต้องค้นหาพารามิเตอร์สำหรับสตริงย่อยแบบง่ายในภาษาใดก็ตาม มันคือสตริงย่อย (เริ่มต้น, ความยาว) หรือซับสตริง (เริ่ม, สิ้นสุด) และรวมอยู่ในสตริงหรือไม่?
James Anderson

1
@JamesAnderson - สตริงย่อยที่มีชื่อว่าพารามิเตอร์จะช่วยคุณแก้ปัญหาได้อย่างไร คุณยังคงต้องค้นหาพารามิเตอร์เพื่อที่จะทราบว่าชื่อของพารามิเตอร์ที่สองคืออะไร (เว้นแต่ว่าทั้งสองฟังก์ชั่นมีอยู่และคุณสมบัติความหลากหลายของภาษาช่วยให้พารามิเตอร์ประเภทเดียวกันกับชื่อที่แตกต่างกัน)
mouviciel

6
@mouviciel: พารามิเตอร์ที่มีชื่อไม่ได้ใช้งานมากเลยสำหรับนักเขียนแต่ที่ยอดเยี่ยมสำหรับผู้อ่าน เราทุกคนรู้ว่าชื่อตัวแปรสำคัญสำหรับการสร้างโค้ดที่อ่านได้และพารามิเตอร์ที่มีชื่อช่วยให้ผู้สร้างอินเทอร์เฟซเพื่อให้ชื่อพารามิเตอร์ที่ดีเช่นเดียวกับชื่อฟังก์ชั่นที่ดีทำให้มันง่ายขึ้นสำหรับคนที่ใช้อินเตอร์เฟสนั้น
Phoshi

@Phoshi - คุณถูกต้อง ฉันลืมความสำคัญของการอ่านรหัสเมื่อฉันเขียนความคิดเห็นก่อนหน้าของฉัน
mouviciel

14

พารามิเตอร์ที่มีชื่อทำให้รหัสอ่านง่ายขึ้นเขียนได้ยากขึ้น

เมื่อฉันกำลังอ่านโค้ดส่วนหนึ่งพารามิเตอร์ที่มีชื่อสามารถแนะนำบริบทที่ทำให้โค้ดเข้าใจง่ายขึ้น Color(1, 102, 205, 170)พิจารณาเช่นคอนสตรัคนี้: นั่นหมายความว่าอย่างไรบนโลก? แน่นอนว่าColor(alpha: 1, red: 102, green: 205, blue: 170)จะอ่านง่ายกว่ามาก แต่อนิจจาที่คอมไพเลอร์กล่าวว่า“ไม่” - Color(a: 1, r: 102, g: 205, b: 170)มันต้องการ เมื่อเขียนโค้ดโดยใช้พารามิเตอร์ที่มีชื่อคุณใช้เวลาโดยไม่จำเป็นในการค้นหาชื่อที่ถูกต้องซึ่งจะง่ายกว่าที่จะลืมชื่อที่แน่นอนของพารามิเตอร์บางตัวมากกว่าที่จะลืมคำสั่งซื้อของพวกเขา

ครั้งนี้ฉันบิตเมื่อใช้DateTimeAPI ที่มีสองคลาสพี่น้องสำหรับคะแนนและระยะเวลากับอินเทอร์เฟซที่เหมือนกันเกือบ ในขณะที่DateTime->new(...)ยอมรับการsecond => 30โต้แย้งความDateTime::Duration->new(...)ต้องการseconds => 30และความคล้ายคลึงสำหรับหน่วยอื่น ๆ ใช่มันสมเหตุสมผลแล้ว แต่สิ่งนี้แสดงให้ฉันเห็นว่าการตั้งชื่อพารามิเตอร์ใช้งานง่าย

ชื่อที่ไม่ถูกต้องไม่ทำให้อ่านง่ายขึ้น

อีกตัวอย่างหนึ่งที่พารามิเตอร์ที่มีชื่อไม่ดีอาจเป็นภาษาR โค้ดส่วนนี้สร้างพล็อตข้อมูล:

plot(plotdata$n, plotdata$mu, type="p", pch=17,  lty=1, bty="n", ann=FALSE, axes=FALSE)

คุณเห็นอาร์กิวเมนต์ตำแหน่งสองตำแหน่งสำหรับแถวข้อมูลxและyจากนั้นรายการพารามิเตอร์ที่มีชื่อ มีตัวเลือกเพิ่มเติมพร้อมค่าเริ่มต้นและมีเฉพาะรายการที่มีค่าเริ่มต้นที่ฉันต้องการเปลี่ยนหรือระบุอย่างชัดเจน เมื่อเราเพิกเฉยว่ารหัสนี้ใช้หมายเลขเวทย์มนตร์และอาจได้รับประโยชน์จากการใช้ enums (ถ้า R มีข้อใดข้อหนึ่ง!) ปัญหาคือชื่อพารามิเตอร์เหล่านี้ส่วนใหญ่จะอ่านไม่ออก

  • pchอันที่จริงแล้วก็คือพล็อตตัวละคร, glyph ที่จะถูกดึงสำหรับทุกจุดข้อมูล 17เป็นวงกลมที่ว่างเปล่าหรืออะไรทำนองนั้น
  • ltyเป็นประเภทเส้น นี่1คือเส้นทึบ
  • btyเป็นประเภทกล่อง การตั้งค่าให้"n"หลีกเลี่ยงกล่องที่วาดรอบพล็อต
  • ann ควบคุมลักษณะที่ปรากฏของคำอธิบายประกอบของแกน

สำหรับคนที่ไม่ทราบความหมายของตัวย่อแต่ละตัวเลือกเหล่านี้ค่อนข้างสับสน สิ่งนี้ยังแสดงให้เห็นว่าเพราะเหตุใด R จึงใช้ป้ายกำกับเหล่านี้: ไม่ใช่รหัสการจัดทำเอกสารด้วยตนเอง แต่ (เป็นภาษาที่พิมพ์แบบไดนามิก) เป็นกุญแจในการจับคู่ค่ากับตัวแปรที่ถูกต้อง

คุณสมบัติของพารามิเตอร์และลายเซ็น

ลายเซ็นฟังก์ชันอาจมีคุณสมบัติดังต่อไปนี้:

  • อาร์กิวเมนต์สามารถสั่งซื้อหรือเรียงลำดับ
  • ชื่อหรือไม่มีชื่อ
  • จำเป็นหรือเป็นทางเลือก
  • ลายเซ็นสามารถโอเวอร์โหลดได้ตามขนาดหรือประเภท
  • และสามารถมีขนาดที่ไม่ระบุด้วย varargs

ภาษาที่ต่างกันมีพิกัดที่แตกต่างกันของระบบนี้ ใน C อาร์กิวเมนต์จะถูกจัดเรียงไม่มีชื่อจำเป็นต้องใช้เสมอและสามารถเป็น varargs ได้ ใน Java สถานการณ์คล้ายกันยกเว้นว่าลายเซ็นนั้นสามารถโอเวอร์โหลดได้ ใน Objective C ลายเซ็นจะได้รับคำสั่งชื่อจำเป็นและไม่สามารถโหลดได้มากเกินไปเพราะมันเป็นเพียงน้ำตาลรอบ ๆ C

ภาษาที่พิมพ์แบบไดนามิกด้วย varargs (อินเตอร์เฟสบรรทัดคำสั่ง, Perl, ... ) สามารถเลียนแบบพารามิเตอร์ที่มีชื่อเป็นตัวเลือก ภาษาที่มีการโหลดมากเกินไปขนาดลายเซ็นต์จะมีบางอย่างเช่นพารามิเตอร์ตัวเลือกเพิ่มเติม

วิธีที่จะไม่ใช้งานพารามิเตอร์ที่กำหนดชื่อ

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

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

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

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

พิจารณาสิ่งนี้ในแง่ของการพิมพ์ย่อยและหลักการทดแทน Liskov - ในผลลัพธ์ที่คอมไพล์คำสั่งเดียวกันควรจะสามารถเรียกใช้เมธอดบนชนิดย่อยที่มีพารามิเตอร์ที่มีชื่อใหม่และบน supertype

การใช้งานที่เป็นไปได้

หากเราไม่สามารถมีคำสั่งที่ชัดเจนดังนั้นเราจำเป็นต้องมีโครงสร้างข้อมูลที่ไม่มีการเรียงลำดับ

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

    ที่จริงแล้วความต้องการพื้นที่สามารถลดลงได้โดยใช้การรวมสตริงซึ่งสามารถลดการเปรียบเทียบสตริงในภายหลังเพื่อเปรียบเทียบตัวชี้ (ยกเว้นเมื่อไม่สามารถรับประกันได้ว่าสตริงสแตติกจะถูกพูลจริง ๆ แล้วในกรณีนี้ทั้งสองสตริงจะต้องเปรียบเทียบ ดูรายละเอียด)

  • แต่เราสามารถส่งผ่านโครงสร้างข้อมูลที่ชาญฉลาดซึ่งทำงานเป็นพจนานุกรมของอาร์กิวเมนต์ที่มีชื่อ สิ่งนี้มีราคาถูกทางด้านผู้โทรเนื่องจากชุดของคีย์เป็นที่รู้จักกันในตำแหน่งการโทร สิ่งนี้จะอนุญาตให้สร้างฟังก์ชันแฮชที่สมบูรณ์แบบหรือเพื่อคำนวณคู่ชีวิตใหม่ ผู้รับสายจะยังคงต้องทดสอบการมีอยู่ของชื่อพารามิเตอร์ที่เป็นไปได้ทั้งหมดซึ่งค่อนข้างแพง Python ใช้สิ่งนี้เช่นนี้

ดังนั้นในกรณีส่วนใหญ่ก็มีราคาแพงเกินไป

หากฟังก์ชั่นที่มีพารามิเตอร์ที่ระบุชื่อนั้นสามารถขยายได้อย่างเหมาะสมจะไม่สามารถสันนิษฐานได้ว่าการเรียงลำดับขั้นสุดท้าย ดังนั้นจึงมีเพียงสองวิธี:

  • ทำให้คำสั่งของชื่อ params เป็นส่วนหนึ่งของลายเซ็นและไม่อนุญาตในภายหลังการเปลี่ยนแปลง สิ่งนี้มีประโยชน์สำหรับรหัสการทำเอกสารด้วยตัวเอง แต่ไม่ช่วยให้มีอาร์กิวเมนต์ที่เป็นทางเลือก
  • ส่งผ่านโครงสร้างข้อมูลคีย์ - ค่าไปยังผู้รับซึ่งจะต้องดึงข้อมูลที่เป็นประโยชน์ การเปรียบเทียบนี้มีราคาแพงมากและมักจะเห็นเฉพาะในภาษาสคริปต์โดยไม่เน้นประสิทธิภาพ

ข้อผิดพลาดอื่น ๆ

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

ปัญหาเกี่ยวกับการจำลองของอาร์กิวเมนต์ที่มีชื่อคือการขาดการตรวจสอบแบบคงที่ในด้านของผู้โทร นี่เป็นเรื่องง่ายโดยเฉพาะอย่างยิ่งที่จะลืมเมื่อผ่านพจนานุกรมของข้อโต้แย้ง (มองคุณ Python) นี้เป็นสิ่งสำคัญเพราะผ่านพจนานุกรมเป็นวิธีแก้ปัญหาที่พบบ่อยเช่นใน foo({bar: "baz", qux: 42})JavaScript: ที่นี่ทั้งประเภทของค่าหรือการมีอยู่หรือไม่มีชื่อบางอย่างสามารถตรวจสอบแบบคงที่

การจำลองชื่อพารามิเตอร์ (ในภาษาที่พิมพ์แบบคงที่)

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

// Java

static abstract class Arguments {
  public String bar = "default";
  public int    qux = 0;
}

void foo(Arguments args) {
  ...
}

/* using an initializer block */
foo(new Arguments(){{ bar = "baz"; qux = 42; }});

3
" it is easier to forget the exact names of some parameters than it is to forget their order" ... นั่นเป็นการยืนยันที่น่าสนใจ
Catskul

1
ตัวอย่างเคาน์เตอร์แรกไม่ใช่ปัญหากับพารามิเตอร์ที่มีชื่อและมีข้อบกพร่องมากขึ้นเกี่ยวกับวิธีที่ภาษาอังกฤษพหูพจน์แมปกับชื่อฟิลด์ในอินเทอร์เฟซ ตัวอย่างตัวนับที่สองนั้นคล้ายกันกับปัญหาที่นักพัฒนาสร้างตัวเลือกการตั้งชื่อที่ไม่ถูกต้อง (ไม่มีตัวเลือกของการส่งผ่านพารามิเตอร์โดยตัวของมันเองจะเป็นเงื่อนไขที่เพียงพอสำหรับการอ่าน - คำถามคือว่ามันเป็นเงื่อนไขที่จำเป็นหรือช่วยเหลือในบางกรณี)
mtraceur

1
+1 สำหรับคะแนนโดยรวมเกี่ยวกับค่าใช้จ่ายในการใช้งานและการแลกเปลี่ยนเพื่อทำพารามิเตอร์ที่มีชื่อ ฉันแค่คิดว่าการเริ่มต้นจะสูญเสียคน
mtraceur

@mtraceur คุณมีประเด็น ตอนนี้ 5 ปีต่อมาฉันอาจจะเขียนคำตอบต่างออกไป หากคุณต้องการคุณสามารถแก้ไขคำตอบของฉันเพื่อลบสิ่งที่เป็นประโยชน์น้อย (โดยปกติการแก้ไขดังกล่าวจะถูกปฏิเสธเนื่องจากขัดต่อเจตนาของผู้เขียน แต่ที่นี่ฉันสบายดี) เช่นตอนนี้ฉันเชื่อว่าปัญหาพารามิเตอร์ที่ตั้งชื่อไว้เป็นเพียงข้อ จำกัด ของภาษาแบบไดนามิกและพวกเขาควรได้รับระบบชนิด เช่น JavaScript มีโฟลว์และ TypeScript, Python มี MyPy ด้วยการรวม IDE ที่เหมาะสมซึ่งช่วยลดปัญหาการใช้งานส่วนใหญ่ ฉันยังคงรออะไรบางอย่างใน Perl
อมร

7

ด้วยเหตุผลเดียวกับที่เอกสารของฮังการีไม่ได้ใช้กันอย่างแพร่หลายอีกต่อไป Intellisense (หรือเทียบเท่าทางศีลธรรมในที่ไม่ใช่ของ Microsoft IDE) IDE สมัยใหม่ส่วนใหญ่จะบอกทุกสิ่งที่คุณจำเป็นต้องรู้เกี่ยวกับพารามิเตอร์โดยเพียงเลื่อนเมาส์ไปเหนือการอ้างอิงพารามิเตอร์

ที่กล่าวว่าหลายภาษารองรับพารามิเตอร์ชื่อรวมถึง C # และ Delphi ใน C # เป็นตัวเลือกดังนั้นคุณไม่จำเป็นต้องใช้มันหากคุณไม่ต้องการและมีวิธีอื่นในการประกาศสมาชิกโดยเฉพาะเช่นการเริ่มต้นวัตถุ

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


4
Python ใช้พารามิเตอร์ที่มีชื่อและมันเป็นคุณสมบัติที่ยอดเยี่ยมของภาษา ฉันหวังว่าภาษาอื่นจะใช้มัน มันทำให้การขัดแย้งเริ่มต้นง่ายขึ้นเมื่อคุณไม่ได้ถูกบังคับอีกต่อไปเช่นเดียวกับใน C ++ เพื่อระบุข้อโต้แย้งใด ๆ "ก่อน" ค่าเริ่มต้น (ตามที่คุณมีในย่อหน้าสุดท้ายของคุณมันเป็นวิธีที่หลามไปโดยไม่มีการโหลดมากเกินไป ... อาร์กิวเมนต์เริ่มต้นและอาร์กิวเมนต์ชื่อให้คุณทำสิ่งเดียวกันทั้งหมด) อาร์กิวเมนต์ที่มีชื่อทำให้รหัสที่อ่านง่ายขึ้น เมื่อคุณมีสิ่งที่ชอบsin(radians=2)คุณไม่จำเป็นต้องมี "Intellisense"
Gort the Robot

2

Bash รองรับรูปแบบการเขียนโปรแกรมนี้อย่างแน่นอนและทั้ง Perl และ Ruby รองรับการส่งผ่านรายการพารามิเตอร์ชื่อ / ค่า (เช่นเดียวกับภาษาใด ๆ ที่สนับสนุนแฮช / แผนที่ดั้งเดิม) ไม่มีอะไรหยุดคุณจากการเลือกกำหนด struct / record หรือ hash / map ซึ่งแนบชื่อกับพารามิเตอร์

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

โปรดทราบว่าโปรแกรมเมอร์ที่มีประสบการณ์ได้คุ้นเคยกับพารามิเตอร์การส่งผ่านตามคำสั่ง / สล็อต คุณอาจพบว่าสำนวนนี้มีค่าก็ต่อเมื่อคุณมีข้อโต้แย้งมากกว่าสองสามข้อ (พูด> 5/6) และเนื่องจากข้อโต้แย้งจำนวนมากมักจะบ่งบอกถึงวิธีการที่ซับซ้อน (สุดเหวี่ยง) คุณอาจพบว่าสำนวนนี้เป็นประโยชน์ต่อวิธีการที่ซับซ้อนที่สุดเท่านั้น


2

ฉันคิดว่ามันเป็นเหตุผลเดียวกันกับที่ c # ได้รับความนิยมมากกว่า VB.net ในขณะที่ VB.NET นั้น "อ่านแล้ว" ได้มากกว่าเช่นคุณพิมพ์ "end if" แทนที่จะเป็นวงเล็บปิด แต่มันก็กลายเป็นสิ่งที่มากกว่าที่จะวางโค้ดและในที่สุดก็ทำให้เข้าใจยากขึ้น

ปรากฎว่าสิ่งที่ทำให้โค้ดเข้าใจง่ายกว่าคือความรัดกุม ยิ่งน้อยยิ่งดี ชื่อพารามิเตอร์ของฟังก์ชั่นนั้นค่อนข้างชัดเจนอยู่แล้วและอย่าไปไกลขนาดนั้นเพื่อช่วยให้คุณเข้าใจโค้ด


1
ฉันไม่เห็นด้วยอย่างรุนแรงว่า "น้อยกว่าดีกว่า" ผู้ชนะการแข่งขันกอล์ฟรหัสจะเป็นโปรแกรมที่ "ดีที่สุด"
Riley Major

2

พารามิเตอร์ที่มีชื่อเป็นวิธีการแก้ปัญหาในที่refactoringรหัสแหล่งที่มาและไม่ได้มีเจตนาที่จะทำให้รหัสที่มาเพิ่มเติมสามารถอ่านได้ พารามิเตอร์ที่มีชื่อถูกใช้เพื่อช่วยคอมไพเลอร์ / parser ในการแก้ไขค่าเริ่มต้นสำหรับการเรียกใช้ฟังก์ชัน หากคุณต้องการให้โค้ดอ่านง่ายขึ้นกว่าเพิ่มความคิดเห็นที่มีความหมาย

ภาษาที่ยากที่จะ refactor มักจะสนับสนุนพารามิเตอร์ชื่อเพราะfoo(1)จะไปทำลายเมื่อลายเซ็นของfoo()การเปลี่ยนแปลง แต่เป็นโอกาสน้อยที่จะทำลายความพยายามที่กำหนดให้น้อยลงจากโปรแกรมเมอร์ที่จะทำการเปลี่ยนแปลงfoo(name:1)foo

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

foo(int weight, int height, int age = 0);

โปรแกรมเมอร์ส่วนใหญ่จะทำสิ่งต่อไปนี้

foo(int weight, int height, int age = 0, string gender = null);

ตอนนี้ไม่จำเป็นต้องทำการปรับโครงสร้างใหม่และฟังก์ชั่นสามารถดำเนินการในโหมดดั้งเดิมเมื่อgenderเป็นโมฆะ

เฉพาะgenderค่าอยู่ในขณะนี้Hardcodedageเข้าสู่การเรียกร้องให้ ดังตัวอย่างนี้:

 foo(10,10,0,"female");

โปรแกรมเมอร์ดูนิยามของฟังก์ชันเห็นว่าageมีค่าเริ่มต้น0และใช้ค่านั้น

ตอนนี้ค่าเริ่มต้นสำหรับageในการกำหนดฟังก์ชั่นจะไร้ประโยชน์อย่างสมบูรณ์

พารามิเตอร์ที่มีชื่อช่วยให้คุณสามารถหลีกเลี่ยงปัญหานี้

foo(weight: 10, height: 10, gender: "female");

สามารถเพิ่มพารามิเตอร์ใหม่fooและคุณไม่ต้องกังวลเกี่ยวกับลำดับที่เพิ่มเข้ามาและคุณสามารถเปลี่ยนค่าเริ่มต้นโดยรู้ว่าค่าเริ่มต้นที่คุณตั้งไว้เป็นค่าเริ่มต้นจริง

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