ทำไมคำว่า“ if elif else” แทบไม่เคยอยู่ในรูปแบบตารางเลย?


73
if   i>0 : return sqrt(i)  
elif i==0: return 0  
else     : return 1j * sqrt(-i)

VS

if i>0:  
   return sqrt(i)  
elif i==0:  
   return 0  
else:  
   return 1j * sqrt(-i)  

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

กรณีเดียวที่ปัญหานี้อาจเกิดขึ้นได้ก็ต่อเมื่อรหัสเปลี่ยนไป ในกรณีนี้ฉันคิดว่ามันเหมาะสมอย่างยิ่งที่จะทำการปรับรหัสให้อยู่ในรูปแบบที่ยาวและเยื้อง ทุกคนทำวิธีที่สองเพียงเพราะวิธีที่เคยทำมาเสมอหรือไม่ การเป็นผู้สนับสนุนของปีศาจฉันคิดว่าอีกเหตุผลหนึ่งอาจเป็นเพราะผู้คนพบสองรูปแบบที่แตกต่างกันขึ้นอยู่กับความซับซ้อนของคำสั่ง if / else ที่ทำให้สับสน? ความเข้าใจใด ๆ ที่จะได้รับการชื่นชม


91
เพราะคนพบว่าตัวเลือกที่ 2 อ่านง่ายกว่า
GrandmasterB

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

47
@horta "กรณีเดียวที่อาจเป็นปัญหาคือรหัสเปลี่ยนแปลงและจะยาวขึ้น" - คุณไม่ควรคิดว่ารหัสส่วนหนึ่งจะไม่ถูกเปลี่ยน การปรับโครงสร้างโค้ดนั้นจะทำให้วงจรชีวิตของซอฟต์แวร์ส่วนใหญ่มีขนาดใหญ่
Charles Addis

7
@horta: ไม่มีอะไรจะทำกับฉัน มันคือรหัส ในบริบทของ codebase ที่ฉันอ่านฉันต้องการดูว่า statement (และการสร้างภาษาอื่น ๆ ) มีการจัดรูปแบบอย่างสม่ำเสมอโดยไม่มีกรณีขอบหรือไม่ ไม่ใช่ว่าฉันเรียนรู้ที่จะอ่านโค้ดในวิธีเฉพาะฉันสามารถอ่านได้ดี แต่มันอ่านง่ายขึ้นถ้าทุกอย่างเหมือนกัน อีกครั้งไม่เหมือนกันกับฉันเหมือนกับรหัสที่เหลือ
GManNickG

44
นอกจากนี้ debuggers ส่วนใหญ่จะขึ้นอยู่กับสาย ไม่สามารถวางเบรกพอยต์ในคำสั่งที่อยู่ภายในifถ้าอยู่ในบรรทัดเดียวกัน
isanae

คำตอบ:


93

เหตุผลหนึ่งอาจเป็นเพราะคุณไม่ได้ใช้ภาษาที่เป็นที่นิยม

ตัวอย่างเคาน์เตอร์สองสาม:

Haskell พร้อมการ์ดและลวดลาย:

sign x |  x >  0        =   1
       |  x == 0        =   0
       |  x <  0        =  -1

take  0     _           =  []
take  _     []          =  []
take  n     (x:xs)      =  x : take (n-1) xs

Erlang ด้วยรูปแบบ:

insert(X,Set) ->
    case lists:member(X,Set) of
        true  -> Set;
        false -> [X|Set]
    end.

Emacs lisp:

(pcase (get-return-code x)
  (`success       (message "Done!"))
  (`would-block   (message "Sorry, can't do it now"))
  (`read-only     (message "The shmliblick is read-only"))
  (`access-denied (message "You do not have the needed rights"))
  (code           (message "Unknown return code %S" code)))

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


10
ฉัน upvoting นี้และเห็นด้วยโดยทั่วไป แต่รู้สึกผูกพันที่จะชี้ให้เห็นว่า 1. สิ่งเหล่านี้เป็นผลตอบแทนเล็กน้อย 2. Haskeller ชอบตัวบ่งชี้สั้น ๆ ที่ตลกขบขันนอกเหนือไปจากภาษาของตัวมันเองและ 3. ภาษาที่ใช้งานได้มักจะแสดงออกตาม และแม้กระทั่งภาษาที่จำเป็นก็มีมาตรฐานสำหรับการแสดงออกที่แตกต่างจากคำพูด หากสหกรณ์เขียนตัวอย่างเดิมกับการใช้งานฟังก์ชั่นที่เขาอาจจะได้รับการแนะนำที่แตกต่างกัน ...
Jared สมิ ธ

3
@ JaredSmith ขอบคุณสำหรับการแยกตามนิพจน์ / คำสั่ง - ฉันคิดว่ามันอาจจะเหมาะสมกว่าการใช้งาน / ความจำเป็น ทับทิมอีกครั้งเกือบจะเป็นพื้นฐานของการแสดงออกและไม่ได้ใช้การประชุมนั้นบ่อยครั้ง (ข้อยกเว้นสำหรับทุกสิ่ง) เกี่ยวกับจุดที่ 1 และ 2 ฉันพบ 50% + ของรหัส Haskell จริงที่จะเป็น "ผลตอบแทนเล็กน้อย" ที่เป็นเพียงส่วนหนึ่งของสิ่งที่ใหญ่กว่า - มันเป็นเพียงวิธีการเขียนโค้ดนั้น - ไม่ใช่แค่ในตัวอย่างที่นี่ ตัวอย่างเช่นใกล้กับครึ่งหนึ่งของฟังก์ชั่นที่นี่เป็นหนึ่งในหนึ่ง / สองสมุทร (บางบรรทัดใช้เค้าโครงตาราง)
viraptor

ใช่. ฉันไม่ใช่ Haskeller แต่ทำ ocaml และพบว่าการจับคู่รูปแบบมีแนวโน้มที่จะรัดกุมมากกว่าสวิตช์ที่มีเหตุผลเชิงตรรกะและฟังก์ชัน polymorphic ครอบคลุมพื้นดินมากมาย ฉันคิดว่าคลาสประเภทของ Haskell จะขยายขอบเขตความครอบคลุมนั้นให้ดียิ่งขึ้นไปอีก
Jared Smith

ฉันคิดว่ามันเป็นไวยากรณ์ของรูปแบบกรณีที่ส่งเสริมสิ่งนั้น เนื่องจากมีความรัดกุมและมักจะใกล้กับตัวพิมพ์ใหญ่สั้นทำให้ง่ายต่อการแสดงเป็นตัวต่อแบบหนึ่ง ฉันมักจะทำสิ่งนี้ด้วยคำสั่ง switch-case สั้น ๆ ด้วยเหตุผลที่คล้ายกัน if-elseแม้ว่าโดยทั่วไปข้อความตามตัวอักษรจะยังคงแพร่กระจายข้ามหลายบรรทัดแม้ว่าจะไม่ได้เป็นไตรภาคีอย่างมีประสิทธิภาพก็ตาม
Isiah Meadows

@viraptor ในทางเทคนิคอีก 50% - ของรหัส haskell คือ "คืนที่ไม่สำคัญ" เพราะฟังก์ชั่น haskell ทั้งหมดนั้นบริสุทธิ์และไม่สามารถมีผลข้างเคียงได้ แม้แต่ฟังก์ชั่นที่อ่านและพิมพ์ไปยังบรรทัดคำสั่งเป็นเพียงคำสั่งการส่งคืนที่มีความยาว
Pharap

134

มันอ่านง่ายขึ้น เหตุผลสองสามประการ:

  • เกือบทุกภาษาใช้ไวยากรณ์นี้ (ไม่ใช่ทั้งหมดส่วนใหญ่ - ตัวอย่างของคุณดูเหมือนจะเป็น Python)
  • isanae ชี้ให้เห็นในความคิดเห็นที่ debuggers ส่วนใหญ่เป็นบรรทัด (ไม่ใช่คำสั่งตาม)
  • มันเริ่มดูน่าเกลียดมากขึ้นถ้าคุณต้องใส่เครื่องหมายอัฒภาคหรือวงเล็บปีกกา
  • มันอ่านจากบนลงล่างได้อย่างราบรื่นมากขึ้น
  • ดูเหมือนว่าอ่านไม่ได้อย่างน่ากลัวถ้าคุณมีสิ่งอื่นนอกเหนือจากแถลงการณ์ผลตอบแทนเล็กน้อย
    • ไวยากรณ์ที่มีความหมายเยื้องใด ๆ จะหายไปเมื่อคุณอ่านสกิมโค้ดเนื่องจากโค้ดที่มีเงื่อนไขจะไม่ถูกแยกด้วยสายตา (จากDan Neely )
    • สิ่งนี้จะไม่ดีเป็นพิเศษหากคุณยังคงแก้ไข / เพิ่มรายการลงใน 1 บรรทัดหากมีคำสั่ง
  • สามารถอ่านได้ก็ต่อเมื่อเช็คทั้งหมดของคุณมีความยาวเท่ากัน
  • หมายความว่าคุณไม่สามารถจัดรูปแบบที่ซับซ้อนได้ถ้าข้อความเป็นข้อความหลายข้อความพวกเขาจะต้องเป็นผู้แจ้งเตือน
  • ฉันมีแนวโน้มที่จะสังเกตเห็นข้อบกพร่อง / ลอจิกเมื่ออ่านแนวตั้งทีละบรรทัดไม่พยายามแยกคำหลายบรรทัดด้วยกัน
  • สมองของเราอ่านข้อความที่แคบและสูงกว่าเร็วกว่าข้อความแนวนอน

นาทีที่คุณพยายามทำสิ่งนี้คุณจะต้องเขียนมันใหม่ลงในคำสั่งหลายบรรทัด ซึ่งหมายความว่าคุณเพิ่งเสียเวลา!

นอกจากนี้ผู้คนเพิ่มสิ่งที่ชอบ:

if i>0:  
   print('foobar')
   return sqrt(i)  
elif i==0:  
   return 0  
else:  
   return 1j * sqrt(-i)  

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

หรือสิ่งนี้:

if   i>0 : return sqrt(i)  
elif i==0 and bar==0: return 0  
else     : return 1j * sqrt(-i)

ซึ่งมันน่ารำคาญจริงๆ ไม่มีใครชอบการจัดรูปแบบสิ่งนี้

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

การอ่านไม่ควรขึ้นอยู่กับการตั้งค่า IDE อย่างไรก็ตาม


14
@horta เพราะคุณจะต้องแปลงถ้าคุณจัดรูปแบบวิธีแรกของคุณในตอนแรก? ฉันทั้งหมดเกี่ยวกับการย่อเล็กสุดสำหรับ enderland ในอนาคต การสร้างตารางไวท์สเปซที่น่ารักและการนับช่องว่างและแท็บเพื่ออัปเดตการจัดรูปแบบภาพเมื่อฉันอาจเพิ่มตรรกะบางอย่างให้กับถ้าการตรวจสอบไม่สนุกเลย (ไม่สนใจความหมายของการอ่าน)
enderland

14
@horta เขาไม่จำเป็นต้องบอกว่าเขาไม่สามารถแก้ไขได้เขาบอกว่าเขาต้องแก้ไขมันและนั่นเป็นเวลาที่ใช้ในการจัดรูปแบบที่น่าเบื่อมากกว่าการเขียนโปรแกรม
59

11
@horta: IMHO ในแบบของคุณมักจะอ่านน้อยกว่าและแน่นอนว่ารูปแบบน่ารำคาญกว่ามาก นอกจากนี้ยังสามารถใช้งานได้เมื่อ "ifs" เป็นหนึ่งใน liners ขนาดเล็กซึ่งเป็นกรณีที่ไม่ค่อย ท้ายสุดมันไม่ดีนัก IMHO ที่จะทำการฟอร์แมตแบบ "ถ้า" สองอย่างด้วยเหตุนี้
dagnelies

9
@horta คุณมีความสุขกับการทำงานกับระบบที่ความต้องการระบบ API และความต้องการของผู้ใช้ไม่เคยเปลี่ยนแปลง คุณวิญญาณผู้โชคดี
enderland

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

55

ฉันเป็นผู้เชื่อมั่นใน 'โค้ดอ่านหลายครั้งเขียนไม่กี่ - ดังนั้นการอ่านเป็นสิ่งสำคัญมาก'

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


3
เกี่ยวข้อง: thecodelesscode.com/case/94
Kevin

11
สิ่งนี้อธิบายได้ว่าทำไมผู้คนจึงอนุรักษ์นิยม มันไม่ได้อธิบายว่าทำไมคนเลือกที่จะเขียนรหัสของพวกเขาเป็นวิธีที่เริ่มต้นด้วย
Jørgen Fogh

8
คำถามคือ 'ทำไมฉันเห็นสิ่งนี้บ่อย' ไม่ใช่สไตล์นี้มาจากไหน คำถามทั้งสองนั้นน่าสนใจ ฉันพยายามตอบคำถามที่ฉันคิดว่าถูกถาม
Art Swri

16

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

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

diff --git a/foo.rb b/foo.rb
index 40f7833..694d8fe 100644
--- a/foo.rb
+++ b/foo.rb
@@ -1,8 +1,8 @@
 class Foo

   def initialize(options)
-    @cached_metadata = options[:metadata]
-    @logger          = options[:logger]
+    @metadata = options[:metadata]
+    @logger   = options[:logger]
   end

 end

ตอนนี้สมมติว่าในเวลาเฉลี่ยในสาขาอื่นโปรแกรมเมอร์ได้เพิ่มบรรทัดใหม่ในบล็อกของรหัสที่จัดตำแหน่ง:

diff --git a/foo.rb b/foo.rb
index 40f7833..86648cb 100644
--- a/foo.rb
+++ b/foo.rb
@@ -3,6 +3,7 @@ class Foo
   def initialize(options)
     @cached_metadata = options[:metadata]
     @logger          = options[:logger]
+    @kittens         = options[:kittens]
   end

 end

การรวมสาขานั้นจะล้มเหลว:

wayne@mercury:/tmp/foo$ git merge add_kittens
Auto-merging foo.rb
CONFLICT (content): Merge conflict in foo.rb
Automatic merge failed; fix conflicts and then commit the result.

หากรหัสที่กำลังแก้ไขไม่ได้ใช้การจัดตำแหน่งแบบตารางการผสานจะสำเร็จโดยอัตโนมัติ

(คำตอบนี้คือ "คัดลอกผลงาน" จากบทความของฉันเองที่ทำให้การจัดแนวแบบตารางไม่เป็นระเบียบในโค้ด)


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

7
@horta สำหรับเครื่องมือการผสานเพื่อแก้ไขพื้นที่สีขาวในลักษณะที่ไม่ได้ทำลายรหัสเกือบทุกครั้งมันจะต้องเข้าใจในสิ่งที่มันสามารถปรับเปลี่ยนพื้นที่สีขาวโดยไม่ต้องเปลี่ยนความหมายของรหัส นอกจากนี้ยังจะต้องเข้าใจการจัดตำแหน่งแบบตารางเฉพาะที่ใช้ นั่นจะไม่เพียงขึ้นกับภาษา (Python!) แต่อาจต้องใช้เครื่องมือในการทำความเข้าใจโค้ดในระดับหนึ่ง ในทางกลับกันการผสานบรรทัดตามนั้นสามารถทำได้โดยไม่ต้องใช้ AI และบ่อยครั้งที่รหัสไม่ถูกทำลาย
Wayne Conrad

Gotcha ดังนั้นดังที่ได้กล่าวไว้ในความคิดเห็นจนกว่าเราจะมีรูปแบบอินพุตของ IDE หรือการเขียนโปรแกรมที่รวมตารางลงในรูปแบบโดยตรงปัญหาการใช้เครื่องมือจะอยู่ที่นั่นเพียงทำให้ชีวิตลำบากสำหรับพวกเราที่ชอบโต๊ะ
horta

1
@horta ถูกต้อง ส่วนใหญ่ของฉันคัดค้านการจัดตำแหน่งแบบตารางในรหัสสามารถไปด้วยเครื่องมือขั้นสูงเพียงพอ
Wayne Conrad

8

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

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


จริง ฉันสังเกตเห็นตัวแก้ไขข้อความที่ฉันใช้ (vim) มีการสนับสนุนที่น่ากลัวสำหรับการจัดรูปแบบตารางหรือแม้แต่ข้อความกว้าง ฉันไม่ได้เห็นโปรแกรมแก้ไขข้อความอื่นดีกว่านี้มาก
Horta

6

มีคำสั่ง 'สวิตช์' ที่ให้สิ่งประเภทนี้สำหรับกรณีพิเศษ แต่ฉันคิดว่านั่นไม่ใช่สิ่งที่คุณกำลังถาม

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

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


1
OP switchดูเหมือนจะใช้งูใหญ่จึงไม่มี
Jared Smith

2
"3 ถ้างบแสดงดีที่สุดในรูปแบบดั้งเดิม แต่ถ้าคุณมี 20" ... จากนั้นคุณมีปัญหาที่ใหญ่กว่าที่จะคิด! :)
กริมม์ Opiner

@GrimmTheOpiner หากคุณกำลังเขียนตัวแยกวิเคราะห์ภาษาหรือตัวระบุสตริง AST นั่นเป็นสิ่งที่เป็นไปได้ในการจัดการ ตัวอย่างเช่นฉันเคยมีส่วนร่วมกับตัวแยกวิเคราะห์ JavaScript ที่ฉันแบ่งฟังก์ชันกับ 15-20 กรณีหนึ่งสำหรับแต่ละประเภทการแสดงออก ฉันแบ่งกรณีส่วนใหญ่ออกไปฟังก์ชั่นของตัวเอง (เพื่อเพิ่มความสมบูรณ์แบบที่โดดเด่น) แต่ความยาวswitchเป็นสิ่งจำเป็น
Isiah Meadows

@ JaredSmith: เห็นได้ชัดว่าswitchเป็นความชั่วร้าย แต่ instantiating พจนานุกรมจากนั้นทำการค้นหาเพื่อที่จะทำการแยกกิ่งเล็ก ๆ น้อย ๆ ไม่ได้เป็นความชั่วร้าย ...
Mark K Cowan

1
@ MarkKCowan โอ้ฉันจับการเสียดสี แต่คิดว่าคุณใช้มันเพื่อเยาะเย้ยฉัน ไม่มีบริบทบนอินเทอร์เน็ตและอะไร
Jared Smith

1

หากการแสดงออกของคุณเป็นเรื่องง่ายภาษาการเขียนโปรแกรมส่วนใหญ่มีตัวดำเนินการย่อย:

return  ( i > 0  ) ? sqrt( i)
      : ( i == 0 ) ? 0
        /* else */ : 1j * sqrt( -i )

นี่เป็นรูปแบบตารางแบบย่อที่สามารถอ่านได้ แต่ส่วนสำคัญคือ: ฉันเห็นภาพรวมของการกระทำ "สำคัญ" นี่คือข้อความสั่งคืนสินค้า! และค่าจะตัดสินใจโดยเงื่อนไขบางอย่าง

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

if ( i > 0 )
{
    throw new InvalidInputException(...);
}
else if ( i == 0 )
{
    return 0;
}
else
{
    log( "Calculating sqrt" );
    return sqrt( -i );
}

7
ที่จริงแล้วฉันพบว่า "รูปแบบตารางสั้น ๆ ที่อ่านได้" ของคุณค่อนข้างเป็นฝันร้ายที่จะอ่านในขณะที่รูปแบบที่เสนอโดย OP นั้นดีมาก
Matteo Italia

@MatteoItalia แล้วรุ่นที่แก้ไขนี้ล่ะ?
Falco

5
ขออภัยยังแย่กว่านั้น ฉันคิดว่ามันมาจากความจริงที่ว่า?และ:ยากที่จะระบุได้มากกว่าif/ elseคำหลักและ / หรือเนื่องจากการเพิ่ม "เสียง" ของสัญลักษณ์
Matteo Italia

@ MatteoItalia: ฉันเคยมีคดีที่มีค่าแตกต่างกันหลายร้อยค่า ค่าตารางทำให้สามารถตรวจสอบข้อผิดพลาดได้ ด้วยหลายบรรทัดมันเป็นไปไม่ได้
gnasher729

1
@ gnasher729 - สำหรับ "ค่า" ที่แตกต่างกัน 100 ค่าโดยทั่วไปฉันพบว่ามันเป็นการดีกว่ามากที่จะประกาศโครงสร้างข้อมูลของแต่ละรายการ "" และแสดงรายการทั้งหมดเป็นตารางในการเริ่มต้นสำหรับอาร์เรย์ของโครงสร้างข้อมูลเหล่านี้ (แน่นอนว่าอาจมีข้อ จำกัด เรื่องภาษาที่นี่) หากรายการใด ๆ ต้องการลักษณะ "การคำนวณ" โครงสร้างรายการสามารถมีตัวชี้หรือการอ้างอิงไปยังฟังก์ชันเพื่อดำเนินการที่จำเป็น สำหรับแอพพลิเคชั่นนี้สิ่งนี้สามารถลดความซับซ้อนของรหัสและทำให้การบำรุงรักษาง่ายขึ้นมาก
Michael Karas

1

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

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

ข้อผิดพลาดที่นิยมอย่างหนึ่งซึ่งมาตรฐานการเข้ารหัสมักจะกล่าวถึงคือ gotcha ตัวเล็ก ๆ นี้: -

if (x == 10)
    do_something();
    do_something_else();

สิ่งนี้ไม่ได้ทำในสิ่งที่คุณคิด เท่าที่ C เป็นห่วงถ้า x 10 แล้วคุณเรียกdo_something()แต่แล้วdo_something_else()ได้รับการเรียกโดยไม่คำนึงถึงความคุ้มค่าของ x เฉพาะการกระทำที่ตามหลังคำสั่ง "ถ้า" เป็นเงื่อนไขเท่านั้น นี่อาจเป็นสิ่งที่ coder ตั้งใจซึ่งในกรณีนี้อาจมีกับดักสำหรับผู้ดูแล หรืออาจไม่ใช่สิ่งที่ coder ตั้งใจซึ่งในกรณีที่มีข้อผิดพลาด มันเป็นคำถามสัมภาษณ์ที่ได้รับความนิยม

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

if (x == 10)
{
    do_something();
    do_something_else();
}

หรือ

if (x == 10)
{
    do_something();
}
do_something_else();

และตอนนี้มันทำงานได้อย่างถูกต้องและชัดเจนสำหรับผู้ดูแล

คุณจะสังเกตเห็นว่าสิ่งนี้ขัดกับรูปแบบตารางของคุณทั้งหมด

ภาษาอื่นบางภาษา (เช่น Python) ดูที่ปัญหานี้และตัดสินใจว่าเนื่องจากตัวแปลงสัญญาณกำลังใช้ช่องว่างเพื่อทำให้รูปแบบชัดเจนจึงควรใช้ช่องว่างแทนวงเล็บปีกกา ดังนั้นใน Python

if x == 10:
    do_something()
    do_something_else()

ทำให้การเรียกทั้งสองdo_something()และdo_something_else()มีเงื่อนไขใน x == 10 ในขณะที่

if x == 10:
    do_something()
do_something_else()

หมายความว่าdo_something()เป็นเงื่อนไขบน x และdo_something_else()ถูกเรียกเสมอ

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


1
ฉันคิดว่าคุณพลาดจุด ปัญหาที่คุณพูดถึงเป็นฝันร้ายที่ไม่ได้มาตรฐานเฉพาะ C แปลก ๆ ที่ทำให้เกิดปัญหาที่คุณพูดถึง หากการเข้ารหัสใน C ฉันจะไม่แนะนำให้ใช้วิธีอื่นถ้าวิธีที่มีรูปแบบตารางที่ฉันแนะนำ แต่เนื่องจากคุณใช้ C คุณจะต้องใช้เครื่องมือจัดฟันทั้งหมดในบรรทัดเดียว เครื่องมือจัดฟันจะทำให้รูปแบบตารางชัดเจนยิ่งขึ้นเพราะทำหน้าที่เป็นตัวคั่น
Horta

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

2
ประเด็นของฉันคือสิ่งนี้ทำให้รูปแบบตารางเป็น clunky มากยิ่งขึ้น อนึ่งไม่ใช่เฉพาะ C - มันถูกแชร์โดยทุกภาษาที่ได้มาจาก C ดังนั้น C ++, C #, Java และ JavaScript ทั้งหมดจึงอนุญาตให้ gotcha เหมือนกัน
เกรแฮม

1
ฉันไม่คิดว่ามันจะเป็นคำสั่งคืน - ฉันเข้าใจว่าความตั้งใจของคุณคือการแสดงข้อความอย่างง่าย ๆ แต่มันจะยุ่งยากมากขึ้น และแน่นอนทันทีที่ข้อความใด ๆ กลายเป็นไม่ง่ายคุณจำเป็นต้องเปลี่ยนการจัดรูปแบบเนื่องจากรูปแบบตารางเป็นไปไม่ได้ที่จะรักษาไว้ หากคุณกำลังทำสิ่งที่ทำให้โค้ดสับสนรหัสที่มีความยาวจะเป็นกลิ่นของตัวเอง (ขีด จำกัด ดั้งเดิมคือ 80 ตัวอักษรวันนี้โดยทั่วไปจะมีประมาณ 130 ตัวอักษร แต่หลักการทั่วไปยังถือว่าคุณไม่ควรเลื่อนเพื่อดูจุดสิ้นสุดของเส้น)
เกรแฮม

1

เค้าโครงแบบตารางจะมีประโยชน์ในบางกรณีที่ จำกัด แต่มีบางครั้งก็มีประโยชน์หาก

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

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

?:มีคำถามเกี่ยวกับการเป็น ใช่มันเป็นผู้ประกอบการที่สาม (หรือฉันชอบที่จะคิดว่ามันคุ้มค่าถ้า) ในบลัชออนครั้งแรกตัวอย่างนี้มีความซับซ้อนเล็กน้อยสำหรับ?: (และมากเกินไป?: ไม่ได้ช่วยให้อ่านง่าย แต่ก็เจ็บ) แต่ด้วยความคิดบางอย่างตัวอย่างที่สามารถจัดเรียงใหม่ได้ด้านล่าง แต่ฉันคิดว่าในกรณีนี้สวิตช์ วิธีการแก้.

if i==0: return 0
return i>0?sqrt(i):(1j*sqrt(-i))

1
คุณอาจต้องทำให้ชัดเจนว่า "?:" สำหรับผู้ที่ไม่ได้ฝึกหัด (ตัวอย่างเช่นอาจเกี่ยวข้องกับคำถาม)
Peter Mortensen

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

@PeterMortensen: หากมือใหม่ไม่รู้ว่ามันหมายถึงอะไรพวกเขาควรอยู่ห่างจากรหัสจนกว่าพวกเขาจะถามคำถามที่ชัดเจนและเรียนรู้
gnasher729

@horta Ternary if ? do stuff : do other stuffคือ คำสั่งเดียวกับ if / else
Navin

1
@Navin Ah, บางทีมันอาจเป็นความล้มเหลวของภาษาที่ฉันใช้บ่อยที่สุด (python) stackoverflow.com/questions/394809/…
horta

-3

ฉันไม่เห็นอะไรผิดปกติกับรูปแบบตาราง ความชอบส่วนตัว แต่ฉันจะใช้ไตรภาคแบบนี้:

return i>0  ? sqrt(i)       :
       i==0 ? 0             :
              1j * sqrt(-i)

ไม่จำเป็นต้องทำซ้ำreturnทุกครั้ง :)


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

ternaries Python เป็นไม่ได้do_something() if condition() else do_something_else() condition() ? do_something() : do_something_else()
Isiah Meadows

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