เหตุใดจึงถือว่าการปฏิบัติที่ไม่ดีในการละเว้นการจัดฟันแบบหยิก [ปิด]


177

ทำไมทุกคนบอกให้ฉันเขียนโค้ดแบบนี้เป็นการปฏิบัติที่ไม่ดี?

if (foo)
    Bar();

//or

for(int i = 0 i < count; i++)
    Bar(i);

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

using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
{
    for (int x = 0; x <= GlowAmount; x++)
    {
        for (int y = 0; y <= GlowAmount; y++)
        {
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
        }
     }
 }
 //versus
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
    for (int x = 0; x <= GlowAmount; x++)
        for (int y = 0; y <= GlowAmount; y++)
            g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));

คุณสามารถรับประโยชน์เพิ่มเติมจากการผูกมัดusingsกันโดยไม่ต้องเยื้องหนึ่งล้านครั้ง

using (Graphics g = Graphics.FromImage(bmp))
{
    using (Brush brush = new SolidBrush(backgroundColor))
    {
        using (Pen pen = new Pen(Color.FromArgb(penColor)))
        {
            //do lots of work
        }
    }
 }
//versus
using (Graphics g = Graphics.FromImage(bmp))
using (Brush brush = new SolidBrush(backgroundColor))
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
    //do lots of work
}

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

if (foo)
    Bar();
    Biz();

คำถาม:

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

6
ฉันเห็นด้วยกับคุณ. ละเว้นพวกเขา ระยะเวลา
Andrei Rînea

67
ใครสนใจเกี่ยวกับการเรียงลำดับสิ่งที่มันเป็นในปี 2010 จอภาพกว้างและราคาถูกและความละเอียดสูง! จอภาพของฉันคือ 2048 X 1152 และฉันมีสองพวกเขา! ความสามารถในการอ่านเป็นสิ่งที่สำคัญยิ่งกว่านั้นการประหยัด 2 เส้นแนวตั้งเมื่อคุณสามารถแนะนำข้อผิดพลาดเล็กน้อยที่หายาก

51
จอภาพกว้างและราคาถูก แต่ไม่สูงและถูก พื้นที่แนวตั้งนั้นหายากกว่าพื้นที่แนวนอน
Adam Says - Reinstate Monica

32
@AdamRuth หมุนไปด้านข้าง :)
Zachary Yates

16
ดังนั้นคุณจะไม่พลาดเหมือนกับแอปเปิ้ลที่มีข้อผิดพลาด SSL ที่พบใน ก.พ. 2014
เรียนรู้

คำตอบ:


183

ที่จริงแล้วครั้งเดียวที่ฉันกัดฉันจริงๆคือตอนที่ฉันกำลังดีบั๊กและแสดงความคิดเห็นในแถบ ():

if(foo)
  // bar();
doSomethingElse();

นอกจากนั้นฉันมักจะใช้:

if(foo) bar();

ซึ่งดูแลกรณีข้างต้น

แก้ไขขอบคุณสำหรับการชี้แจงคำถามฉันเห็นด้วยเราไม่ควรเขียนรหัสไปยังตัวส่วนร่วมที่ต่ำที่สุด


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

23
ฉันไม่ชอบสไตล์ซับเดียวเพราะฉันมักจะมองหาบอดี้ลูปด้านล่าง
Nosredna

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

1
สไตล์หนึ่งบรรทัดยังซ่อนแถบ () จากการครอบคลุมการทดสอบ มันจะดูครอบคลุมแม้ว่า foo จะเป็นเท็จเสมอ
Bohumil Janda

1
นี่เป็นอีกวิธีหนึ่งในการพูดว่า "หากมีแหล่งที่มารวมถึงเครื่องหมายปีกกาผมไม่ต้องเสียเวลากับการแก้ไขจุดบกพร่อง" - การเพิ่มเครื่องมือจัดฟันนั้นง่ายมากและหลีกเลี่ยงข้อผิดพลาดสำหรับบุคคลต่อไป ข้อโต้แย้งเพียงข้อเดียวคือ "การอ่านได้" ซึ่งค่อนข้างผอมบางเนื่องจากนี่เป็นกรณีที่มีบางสิ่งเกิดขึ้นโดยปริยายหากคุณไม่ใช้
Andrew Theken

156

ความเร็วในการอ่าน ...

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

if (condition)
{
    DoSomething();
}

DoSomethingElse();

เร็วกว่าที่ฉันอ่านเล็กน้อย:

if (condition) DoSomething();

DoSomethingElse();

ฉันอ่านมันช้าลงเล็กน้อยถ้ามันเป็นเช่นนี้:

if (condition) DoSomething();
DoSomethingElse();

ฉันอ่านสิ่งนี้ช้ากว่าที่ผ่านมา:

if (condition) 
    DoSomething();
DoSomethingElse();

เพราะฉันไม่สามารถช่วย แต่อ่านมันอีกครั้งในกรณีและสงสัยว่าผู้เขียนตั้งใจ:

if (condition)
{
    DoSomething();
    DoSomethingElse();
}

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

if (condition) 
    DoSomething();
    DoSomethingElse();

29
ปัญหาได้รับการแก้ไขเมื่อในตัวอย่างที่ 4 ของคุณคุณเพียงแค่ใส่บรรทัดว่างหลังจากถ้าคำสั่งแยกจาก DoSomethingElse () นั่นคือสิ่งที่ฉันทำและการอ่านจะเหมือนกับในตัวอย่างที่ 1 (ถ้าไม่ดีกว่า ;-P) อีกสิ่งหนึ่งคือการวางสายในกลุ่ม 2 หรือ 3 อย่างมีนัยสำคัญช่วยให้อ่านง่ายคุณแค่สแกนรหัสเร็วขึ้น
Piotr Owsiak

6
อาจจะเป็นเพราะฉันคุ้นเคยกับ Python แต่การใส่วงเล็บปีกกาแรกในบรรทัดเดียวกับคำสั่ง if ทำให้ฉันอ่าน + เข้าใจได้เร็วขึ้น
Ponkadoodle

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

2
การจัดฟันนั้นชัดเจนโดยธรรมชาติ ฉันจะติดกับที่ขอบคุณ
TheOptimusPrimus

2
ในกรณีสุดท้ายตามล่าผู้แต่งดั้งเดิมและตบเขา ... ;)
ต่อ Lundberg

55

ถ้ามันมีขนาดเล็กเขียนแบบนี้:

if(foo()) bar();

หากมันยาวพอที่จะเจาะเป็นสองบรรทัดให้ใช้เครื่องหมายปีกกา


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

10
ไม่เป็นมิตรกับดีบักเกอร์มากนัก คุณจะตั้งค่าเบรกพอยต์ในส่วน "บาร์" ได้อย่างไร?
Nemanja Trifunovic

9
@Nemanja: เพียงวางเคอร์เซอร์บนแถบ (); และกด F9 ทั้ง VS2005 และ VS2008 จัดการกับเบรกพอยต์อินทราถ้าพวกเขาแยก "คำสั่ง"
GalacticCowboy

4
GalanticCowboy: มีสภาพแวดล้อมมากกว่าที่คุณรู้ :-)

20
แน่นอน แต่เนื่องจากบริบทคือ C # ที่ควรจะครอบคลุมผู้ใช้ส่วนใหญ่ที่สำคัญ ...
GalacticCowboy

47

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

อีกเหตุผลที่ดีสำหรับการใช้เครื่องมือจัดฟันนอกเหนือจากคนที่เพิ่มคำสั่งที่สองใน if คือสิ่งที่อาจเกิดขึ้น

if(a)
   if(b)
     c();
else
   d();

คุณสังเกตว่าประโยคอื่นเป็นจริงของ "if (b)" หรือไม่? คุณอาจทำ แต่คุณจะเชื่อใจใครก็ตามที่คุ้นเคยกับ gotcha นี้หรือไม่?

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


12
นี่เป็นหนึ่งในสองกรณีที่ฉันใช้เครื่องมือจัดฟัน ไม่อย่างนั้น
Andrei Rînea

3
สิ่งนี้ควรถูกเขียนราวกับว่า (&&b) ... ในตำแหน่งแรกที่มีการเชื่อมโยง
alexander.biskop

8
@ alexander.biskop: ไม่แน่นอนเพราะนั่นทำให้บล็อกอื่นมีความหมายที่แตกต่างกัน ( !a || !b) มากกว่าทั้งที่มี ( !a) หรือไม่มี ( a && !b) วงเล็บปีกกาที่เพิ่มเข้ามา
Ben Voigt

1
@Ben Voigt: จริง! ตกลงไป ;-) ครึ่งปีและสอง upvotes ต่อมามีคนตระหนักถึงคำสั่งที่ฉันทำผิด ... เดาว่าฉันไม่ใส่ใจรายละเอียดมากพอส่วนใหญ่เป็นเพราะความตั้งใจที่อยู่เบื้องหลังความคิดเห็นของฉันแตกต่างจากชี้ให้เห็น การเปลี่ยนแปลงทางเทคนิคที่ถูกต้องของ if-clause สิ่งที่ฉันหมายถึงคือข้อความแบบอินไลน์ที่ซ้อนกันหากคำสั่งทั่วไปลดความสามารถในการอ่าน (และการตรวจสอบย้อนกลับของการควบคุมการไหล) อย่างมีนัยสำคัญ imho และด้วยเหตุนี้จึงควรรวมกันเป็นหนึ่งคำสั่ง ไชโย
alexander.biskop

3
@ alexander.biskop: ในขณะเดียวกันการดีบักก็ง่ายขึ้นด้วยซ้อน ifs แต่ละอันด้วยเงื่อนไขที่ง่ายกว่าเนื่องจากคุณสามารถก้าวเข้าสู่แต่ละคนได้
Ben Voigt

35

นี่ไม่ถือว่าเป็นการปฏิบัติที่ไม่ดีเสมอไป โครงการโมโน Coding แนวทางแนะนำที่จะไม่ใช้เครื่องหมายปีกกาถ้ามันไม่จำเป็น เหมือนกันสำหรับGNU มาตรฐานการเข้ารหัส ฉันคิดว่ามันเป็นเรื่องของรสนิยมส่วนตัวเช่นเคยกับมาตรฐานการเข้ารหัส


2
ดูรหัสโมโนดูเหมือนว่าจะค่อนข้างแปลกสำหรับฉันหลังจากอ่านแนวทางทั้งหมด
dance2die

35

เส้นมีราคาถูก โปรเซสเซอร์พลังงานราคาถูก เวลานักพัฒนามีราคาแพงมาก

ตามกฎทั่วไปหากฉันไม่ได้พัฒนาแอพพลิเคชั่นที่สำคัญเกี่ยวกับทรัพยากร / ความเร็วฉันจะทำผิดด้านการเขียนโค้ดที่

(a) ง่ายสำหรับผู้พัฒนารายอื่นที่จะติดตามสิ่งที่ฉันทำ

(b) แสดงความคิดเห็นเฉพาะส่วนของรหัสที่อาจจำเป็นต้องใช้

(c) ง่ายต่อการแก้ไขข้อบกพร่องหากมีสิ่งผิดปกติ

(d) แก้ไขได้ง่ายหากจำเป็นต้องมีในอนาคต (เช่นการเพิ่ม / ลบรหัส)

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

โดยการละเว้นวงเล็บปีกกาในกรณีส่วนใหญ่มันทำให้ฉัน (b), (c) และ (d) ยากขึ้น (หมายเหตุไม่เป็นไปไม่ได้) ฉันจะบอกว่าใช้วงเล็บปีกกาหรือไม่มีผลต่อ (a)


9
ข้อความสุดท้ายของคุณเกี่ยวกับ (a) เป็นความคิดเห็นที่ผู้พัฒนาซอฟต์แวร์จำนวนมากรวมถึงผู้โพสต์อื่น ๆ ที่นี่จะโต้แย้ง
Kelly S. French

34

ฉันชอบความคมชัดที่วงเล็บปีกกาเสนอ คุณรู้แน่ชัดว่ามีความหมายอะไรและไม่ต้องเดาว่ามีใครบางคนเพิ่งทำผิดและทิ้งมันไว้ (และแนะนำบั๊ก) ครั้งเดียวที่ฉันละเว้นพวกเขาคือเมื่อฉันใส่ if และ action บนบรรทัดเดียวกัน ฉันไม่ได้ทำแบบนั้นบ่อยนัก จริง ๆ แล้วฉันชอบช่องว่างที่แนะนำโดยใส่วงเล็บปีกกาไว้บนบรรทัดของตัวเองแม้ว่าจากการเขียนโปรแกรมแบบ K&R เช่นเดียวกับปีที่ผ่านมาการสิ้นสุดบรรทัดด้วยวงเล็บปีกกาเป็นวิธีปฏิบัติที่ฉันต้องทำงานเพื่อเอาชนะถ้า IDE ไม่บังคับใช้ ผม.

if (condition) action();  // ok by me

if (condition) // normal/standard for me
{
   action();
}

23

ฉันคิดว่ามันเป็นเรื่องของแนวทางสำหรับโครงการที่คุณกำลังทำงานและรสนิยมส่วนตัว

ฉันมักจะละเว้นพวกเขาเมื่อพวกเขาไม่ต้องการยกเว้นบางกรณีเช่นต่อไปนี้:

if (something)
    just one statement; // i find this ugly
else
{
    // many
    // lines
    // of code
}

ฉันชอบ

if (something)
{
    just one statement; // looks better:)
}
else
{
    // many
    // lines
    // of code
}

15

หนึ่งในอินสแตนซ์ที่สิ่งนี้สามารถกัดคุณกลับมาในวันเก่าของมาโคร C / C ++ ฉันรู้ว่านี่เป็นคำถาม C # แต่บ่อยครั้งที่มาตรฐานการเข้ารหัสดำเนินการโดยไม่มีเหตุผลว่าทำไมมาตรฐานจึงถูกสร้างขึ้นตั้งแต่แรก

หากคุณไม่ได้ระวังตัวมากเมื่อสร้างมาโครคุณสามารถทำให้เกิดปัญหาได้หากข้อความที่ไม่ได้ใช้ {}

#define BADLY_MADE_MACRO(x) function1(x); function2(x);

if (myCondition) BADLY_MADE_MACRO(myValue)

ตอนนี้อย่าเข้าใจฉันผิดฉันไม่ได้บอกว่าคุณควรทำ {} เพื่อหลีกเลี่ยงปัญหานี้ใน C / C ++ เสมอ แต่ฉันต้องจัดการกับข้อผิดพลาดบางอย่างที่แปลกมากเพราะสิ่งนี้


2
หากรหัสทั้งหมดเท่านั้นประกาศตัวเองเป็นเช่นนี้ ... ถอนหายใจ
นาธานที่แข็งแกร่ง

15

ฉันเคยคิดแบบเดียวกัน

จนกระทั่งวันหนึ่ง (ทำไมมี "วันหนึ่ง" ที่เปลี่ยนชีวิตของคุณตลอดไป?) เราใช้เวลาตั้งแต่ 24 - 36 ชั่วโมงโดยไม่ต้องทำการดีบั๊กการสร้างรหัสเฉพาะการค้นหาว่ามีใครบางคนไม่ใส่วงเล็บรวมกับการเปลี่ยนแปลงการค้นหา / แทนที่ .

มันเป็นอะไรแบบนี้

 if( debugEnabled ) 
      println( "About to save 1 day of work to some very important place.");
 saveDayData();

สิ่งที่เกิดขึ้นหลังจากนั้น

 if( debugEnabled ) 
 //     println( "About to save 1 day of work to some very important place.");
 saveDayData();

ปรากฎว่าระบบสร้างบันทึก 500 mb ทุกวันและเราถูกขอให้หยุด แฟล็กการดีบักไม่เพียงพอดังนั้นการค้นหาและแทนที่ println นั้นเป็นไปตามลำดับ

ถึงกระนั้นเมื่อแอปไปผลิตการตั้งค่าสถานะการแก้ปัญหาถูกปิดและที่สำคัญ "saveDayData" ไม่เคยถูกเรียก

แก้ไข

ตอนนี้ที่เดียวที่ฉันไม่ใช้วงเล็บปีกกาอยู่ในถ้า / ลองสร้าง

if( object != null ) try { 
     object.close();
} catch( .....

หลังจากดูนักพัฒนาที่เก่งแล้วก็ทำเช่นนั้น


3
ฉันไม่เข้าใจ คุณมีตัวแปรที่ควบคุมการดีบัก (debugEnabled) และคุณยังคงใช้ความคิดเห็นเพื่อปิดการใช้งานการดีบัก ??? ทำไมคุณไม่ตั้ง debugEnabled เป็นเท็จ
Igor Popov

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

1
@igor แล้วเพราะพวกเขาต้องการลบการบันทึกหนึ่งบรรทัดไม่ใช่การบันทึกทุกบรรทัด?
gman

14

จะทื่อฉันเห็นมันเป็น:

โปรแกรมโปรแกรมเมอร์ที่ดีป้องกันได้โปรแกรมเมอร์ที่ไม่ดีทำไม่ได้

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

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

โจเอลยังกล่าวถึงเรื่องนี้ในการสร้างรหัสผิดให้ดูผิด

เมื่อคุณได้รับข้อผิดพลาดเล็กน้อยเนื่องจากการจัดฟันที่ขาดหายไปคุณจะได้เรียนรู้ว่าการจัดฟันที่หายไปนั้นดูผิดเพราะคุณรู้ว่ามันเป็นสถานที่ที่มีโอกาสเกิดข้อผิดพลาดอื่นได้


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

14

ฉันมีความสุขมากที่:

foreach (Foo f in foos)
  foreach (Bar b in bars)
    if (f.Equals(b))
      return true;

return false;

โดยส่วนตัวฉันไม่เห็นสาเหตุ

foreach (Foo f in foos)
{
  foreach (Bar b in bars)
  {
    if (f.Equals(b))
    {
      return true;
    }
  }
}

return false;

สามารถอ่านได้มากขึ้น

ใช่เส้นนั้นฟรี แต่ทำไมฉันต้องเลื่อนหน้าและหน้าของรหัสเมื่อมันอาจมีขนาดครึ่งหนึ่ง?

หากมีความแตกต่างในการอ่านหรือการบำรุงรักษาให้แน่ใจว่าใส่วงเล็บใน ... แต่ในกรณีนี้ฉันไม่เห็นเหตุผลใด ๆ

นอกจากนี้ฉันจะใส่เครื่องหมายวงเล็บสำหรับซ้อนกันเสมอถ้าเป็นตำแหน่งที่ฉันซ้อนกันอยู่

if (condition1)
  if (condition2)
    doSomething();
  else (condition2)
    doSomethingElse();

VS

if (condition1)
  if (condition2)
    doSomething();
else (condition2)
  doSomethingElse();

สับสนอย่างมากดังนั้นฉันมักจะเขียนเป็น:

if (condition1)
{
  if (condition2)
    doSomething();
  else (condition2)
    doSomethingElse();
}

เมื่อใดก็ตามที่เป็นไปได้ผมใช้ประกอบ ternary แต่ฉันไม่เคย รังพวกเขา


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

10

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

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


10

ปรัชญาของฉันคือถ้ามันทำให้โค้ดอ่านง่ายขึ้นทำไมไม่ทำ?

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

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


7
แน่นอนว่านี่เป็นเรื่องส่วนตัวมาก การปล่อยทิ้งไว้บางครั้งช่วยเพิ่มความสามารถในการอ่าน
Brian Knoblauch

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

10

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

if(x == y)
   for(/* loop */)
   {
      //200 lines
   }

//rampion's example:
for(/* loop */)
{
   for(/* loop */)
      for(/* loop */)
      {
         //several lines
      }
}

มิฉะนั้นฉันไม่มีปัญหากับมัน


4
ตัวอย่างที่ไม่ดี ในทั้งสองกรณีนี้ผมจะคำนึงถึงว่า 200 เส้นสำหรับการวนซ้ำในวิธีการของตัวเองหรือหลายวิธี
Adam Jaskiewicz

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

2
มันเกิดขึ้น ไม่ได้หมายความว่าควรจะเกิดขึ้น
Adam Jaskiewicz

3
@AdamJaskiewicz ถูกต้อง มันเกิดขึ้น เราต้องคิดเกี่ยวกับสิ่งที่ไม่เกิดขึ้นมากกว่าสิ่งที่ควรจะเกิดขึ้น หากเราสามารถ จำกัด ตัวเองในสิ่งที่จะเกิดขึ้นเราไม่จำเป็นต้องกังวลเกี่ยวกับข้อบกพร่อง
Beska

10

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

ฉันได้เห็น

if (...)
    foo();
    bar();

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

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


ฉันมักจะโต้แย้งกรณีที่ความสอดคล้องมีความสำคัญมากกว่ารูปแบบที่เกิดขึ้นจริงทำไมเราควรยกเว้นเฉพาะในกรณีของการใช้งาน?
Bob

@ บ็อบ: จุดดีและฉันทำมันเป็นครั้งคราวเท่านั้น ฉันไม่อยากจะแกล้งทำเป็นว่าฉันมีเหตุผลจริงที่นี่ :) จริง ๆ แล้วมีเหตุผลที่สมเหตุสมผล - ซ้อนการใช้ (และการใช้งานเท่านั้น) แบบนั้นชัดเจนมากและคุณยังคงจบลงด้วยการบล็อก ฉันไม่เห็นอันตรายทันที
Jon Skeet

ซึ่งไม่ได้บอกว่าไม่มีอันตรายใด ๆ แน่นอน
Jon Skeet

1
ทางออกที่ดีที่สุดสำหรับข้อผิดพลาดนี้: ใช้ Python (ล้อเล่นแน่นอน)
Joel Wietelmann

10

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

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

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

ที่กล่าวว่าบางสิ่งมีการเปลี่ยนแปลงในโลกที่ทำให้ "เจ้าจะใช้เครื่องมือจัดฟันในบล็อกบรรทัดเดียว" วันนี้มีความเกี่ยวข้องน้อยกว่าเมื่อโมเสสนำมันมาให้เรา:

  • ภาษายอดนิยมบางภาษาทำให้ปัญหาหายไปโดยทำให้คอมพิวเตอร์อ่านการเยื้องเช่นเดียวกับที่โปรแกรมเมอร์ทำ (เช่น Python)

  • โปรแกรมแก้ไขของฉันจะจัดรูปแบบโดยอัตโนมัติสำหรับฉันดังนั้นโอกาสที่ฉันจะเข้าใจผิดโดยการเยื้องจึงลดลงมาก

  • TDDหมายความว่าถ้าฉันแนะนำบั๊กเพราะฉันสับสนโดยบล็อกบรรทัดเดียวฉันมีแนวโน้มที่จะค้นพบข้อผิดพลาดได้อย่างรวดเร็ว

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

ในความเป็นจริงมีประโยชน์ที่แตกต่างกันสามารถสร้างการจัดฟันอย่างไร้ความปราณีและละเว้นการจัดฟันบนบล็อกบรรทัดเดียว: เมื่อคุณเห็นวงเล็บปีกกาสัญญาณเตือนเล็ก ๆ สามารถไปที่หัวของคุณว่า "ความซับซ้อนที่นี่! ระวัง!" ลองคิดดูว่านี่เป็นบรรทัดฐานหรือไม่:

if (condition) Foo();   // normal, everyday code

if (condition) 
{
    // something non-trivial hapening; pay attention!
    Foo();
    Bar();
}

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


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

ฉันรู้สึกเหมือนกันกับการจัดฟัน มันคือทั้งหมดที่เกี่ยวกับความซับซ้อน เป็นการดีที่เราจะมีบล็อกบรรทัดเดียว นั่นคือสิ่งที่ฉันเรียกว่าการอ่านไม่ใช่การจัดฟันที่ไม่จำเป็น
Igor Popov

9

จากการประชุมทั้งสาม:

if(addCurleyBraces()) bugFreeSofware.hooray();

และ:

if(addCurleyBraces())
    bugFreeSofware.hooray();

และ (ซึ่งแสดงถึงสไตล์การเยื้องใด ๆ โดยใช้การเปิดและวงเล็บปีกกาปิด):

if(addCurleyBraces()) {
    bugFreeSofware.hooray();
}

ฉันชอบอันสุดท้ายเป็น:

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

8

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

เส้นเป็นอิสระ (เกือบ) ลดจำนวนบรรทัดในรหัสของคุณไม่ควรมีวัตถุประสงค์

และการเยื้องเป็นอิสระจากการใช้รั้ง ในตัวอย่างการ 'ใช้' ของคุณฉันยังคิดว่าคุณควรจะเยื้องพวกเขาแม้ว่าคุณจะไม่ใส่เครื่องมือจัดฟัน


8

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

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

if(x < y)
    x = y;
else
    y = x;

และอีกเช่นนี้

if(x < y)
{
    x = y;
    x++;
}
else
{
    y = x;
    y++;
}

ฉันชอบที่จะเลือกสไตล์ทั่วไปและติดกับมัน :)


7

หนึ่งในปัญหาหลักคือเมื่อคุณมีภูมิภาคของสมุทรหนึ่งและไม่ใช่หนึ่งสมุทรพร้อมกับแยกออกจาก statment ควบคุม ( for, ifคุณมีอะไร) และจุดสิ้นสุดของกฎหมาย

ตัวอย่างเช่น:

for (...)
{
  for (...)
    for (...) 
    {
      // a couple pages of code
    }
  // which for block is ending here?  A good text editor will tell you, 
  // but it's not obvious when you're reading the code
}

4
ทำไมคุณมีโค้ดสองสามหน้าสำหรับลูปของคุณ
Adam Jaskiewicz

b / c ฉันเป็นคนผิวเผินและฉันก็หมกมุ่นกับการกำจัด "ต้นทุน" ของการเรียกฟังก์ชั่น :)
rampion

4
สองสามหน้าของรหัสควรอยู่ในฟังก์ชั่นแยกต่างหากโดยปกติ
Jonathan Leffler

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

7

ฉันเคยเป็นผู้สนับสนุนที่ยิ่งใหญ่ของ "การจัดฟันแบบโค้งเป็นต้อง!" แต่ตั้งแต่ใช้การทดสอบหน่วยฉันพบว่าการทดสอบหน่วยของฉันปกป้องคำสั่งที่ไม่รัดกุมจากสถานการณ์เช่น:

if (foo)
    snafu();
    bar();

ด้วยการทดสอบหน่วยที่ดีฉันสามารถละเว้นวงเล็บปีกกาได้อย่างมั่นใจสำหรับคำสั่งง่ายๆเพื่อปรับปรุงการอ่าน (ใช่ที่สามารถเป็นอัตนัย)

อีกวิธีหนึ่งสำหรับสิ่งที่กล่าวมาข้างต้นฉันมีแนวโน้มที่จะอินไลน์ที่จะมีลักษณะ:

if (foo) snafu();

ด้วยวิธีนี้นักพัฒนาที่ต้องการเพิ่มแถบ () ลงในเงื่อนไขจะมีแนวโน้มที่จะรับรู้ถึงการขาดเครื่องมือจัดฟันแบบโค้งและเพิ่มพวกเขา


2
คุณพูดว่า "ฉันไม่ต้องการ" แล้วก็ให้เหตุผลในการใช้: อ่านง่าย!
tvanfosson

4
ฉันจะไม่พึ่งพาการทดสอบหน่วยเพื่อหาสิ่งนั้น Lint อาจจะเป็นยูนิตทดสอบหมายเลข!
Kristen

2
@ Kristen - ความคิดของการทดสอบหน่วยคือการยืนยันพฤติกรรมของวิธีการ หากการเปลี่ยนแปลงพฤติกรรม (ตามที่อธิบายข้างต้น) การทดสอบหน่วยจะล้มเหลว ฉันไม่เห็นปัญหาในเรื่องนั้น
Liggy

แต่ทำไมต้องใช้การทดสอบหน่วยเพื่อรับความชัดเจนที่ควรได้รับการแก้ไขก่อนไปที่ UT
แอนดรู

7

ใช้วิจารณญาณส่วนตัว

if (foo)
  bar();

ไม่เป็นไร นอกเสียจากว่าคุณจะกังวลเกี่ยวกับสิ่งที่วางไว้ในลักษณะนี้ในภายหลัง:

if (foo)
  bar();
  baz();

หากคุณไม่กังวลเกี่ยวกับปัญญาอ่อนคุณก็สบายดี (ฉันไม่ใช่ - หากพวกเขาไม่สามารถรับรหัสไวยากรณ์พื้นฐานได้นั่นเป็นปัญหาขั้นต่ำที่สุด)>

ในการแลกเปลี่ยนมันสามารถอ่านได้มากขึ้น

เวลาที่เหลือ:

if (foo) {
  bar();
  baz();
}

ซึ่งเป็นที่โปรดปรานของฉันตราบใดที่ฉันจำได้ นอกจากนี้:

if (foo) {
  bar();
  baz();
} else {
  qux();
}

ได้ผลสำหรับฉัน

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


ครั้งเดียวที่ฉันชอบสไตล์แรกคือเมื่อฉันต้องกลับมาทันทีหรือโยนข้อผิดพลาดในกรณีที่มีบางอย่างผิดปกติ กดif (parameter == null) return null;ไลค์
nawfal

7

โอเคนี่เป็นคำถามเก่าที่ตอบไปถึงความตาย ฉันมีสิ่งที่จะเพิ่ม

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

ตอนนี้สำหรับการเพิ่มของฉัน: มีปัญหากับสิ่งนี้:

if (foo) bar();

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

ดังนั้นทำสิ่งนี้:

if (foo)
{
    bar(); //It is easy to put a breakpoint here, and that is useful.
}

2
คลิกขวาที่บาร์แล้วเลือกแทรกเบรกพอยต์ ... ไม่ยากเลย รู้จักเครื่องมือของคุณ
Bob

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

อ๊ะฮ่าคลิกขวาที่ "bar ()" คุณหมายถึงข้อความ Gotcha แน่นอนหรือเพียงแค่กด F9 ...
ศิลา

>> คุณต้องวางเคอร์เซอร์บน "bar ()" หรือคลิกขวาตรงนั้นก่อนกด F9 (ฉันหมายถึงวางเคอร์เซอร์ไว้ตรงนั้นก่อนกด F9 หรือคลิกขวา)
หิน

7

เพื่อที่จะป้องกันไม่ให้มีการจัดฟันด้วยการใช้รหัสพื้นที่มากฉันใช้เทคนิคที่แนะนำในหนังสือรหัสเสร็จสมบูรณ์ :

if (...) {
    foo();
    bar();
}
else {
    ...
}

ฉันไม่เข้าใจว่าทำไมมันถูกปรับลดลงจะช่วยหนึ่งบรรทัดสำหรับวงเล็บทุกคู่ฉันใช้มันตลอดเวลา
Eric

2
นี่เป็นที่รู้จักกันแพร่หลายในสไตล์ K&R ตามหนังสือภาษา C Programming โดย Kernighan และ Ritchie: en.wikipedia.org/wiki/The_C_Programming_Language_(book) และมันก็ไม่ควรทำให้คุณถูก modded
jmucchiello

ขอบคุณ! ฉันคิดว่ามันเป็นแค่รสนิยมส่วนตัว ฉันเคยพบว่าไวยากรณ์นี้น่ารำคาญตัวเอง แต่ฉันนำมาใช้หลังจากอ่าน Code Complete และสนุกกับมันตอนนี้
นาธาน Prather

ฉันอ่านคำตอบทั้งหมดข้างต้นแล้วคิดว่า "ทำไมยังไม่มีใครแนะนำสิ่งนี้เลย" มันทำให้วงเล็บปิดอยู่ในแนวเดียวกับบล็อกที่ปิดนั่นคือ "ถ้า" หรือ "ในขณะที่" ฯลฯ ไม่เป็น "{" ที่ไม่มีความหมาย +1
nickf

หากวงเล็บปีกกาเปิดนั้นวางอยู่บนเส้นด้วยตัวเองบรรทัดifที่ตามด้วยบรรทัดเยื้องเดียวอาจถูกจดจำด้วยสายตาว่าเป็นการควบคุมคำสั่งเดี่ยวโดยไม่ต้องใช้วงเล็บปีกกาใด ๆ ลักษณะเปิดวงเล็บปีกกาโดยตัวเองจึงช่วยประหยัดช่องว่างในสถานการณ์ที่ifคำสั่งควบคุมสิ่งที่มีความหมายการกระทำเดียว (แตกต่างจากลำดับขั้นตอนที่เกิดขึ้นกับมีเพียงขั้นตอนเดียว) ตัวอย่างเช่นif (someCondition)/ 'โยน SomeException ใหม่ (... ) `
supercat

6

สมมติว่าคุณมีรหัส:

if (foo)
    bar();

แล้วมีคนอื่นมาเพิ่ม:

if (foo)
    snafu();
    bar();

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


ประเด็นนี้ได้เกิดขึ้นแล้วในคำถาม
Mike Scott

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

มีรหัสข้อผิดพลาดดังกล่าวหรือไม่?
Bob

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

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

6

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


5

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

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

ฉันเห็นมันชนิดเช่นอาร์กิวเมนต์สำหรับVSif ( foo == 0 ) if ( 0 == foo )หลังอาจป้องกันข้อผิดพลาดสำหรับโปรแกรมเมอร์ใหม่ (และอาจเป็นครั้งคราวสำหรับทหารผ่านศึก) ในขณะที่อดีตจะง่ายต่อการอ่านและเข้าใจได้อย่างรวดเร็วเมื่อคุณรักษารหัส


4

เวลาส่วนใหญ่จะฝังอยู่ในมาตรฐานการเข้ารหัสไม่ว่าจะสำหรับ บริษัท หรือโครงการ FOSS

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

ลองจินตนาการดูว่ามีใครบางคนกำลังเข้าร่วมระหว่าง Python กับภาษา Cish มากกว่าหนึ่งครั้งต่อวัน ... การเยื้องของ Python เป็นส่วนหนึ่งของบล็อกไซแมนติกของภาษา


+1 สำหรับความคิดเห็นเกี่ยวกับหลาม ฉันประหลาดใจอยู่เสมอว่า "โง่" ฉันสามารถเปลี่ยนภาษาได้อย่างต่อเนื่อง
Kena

3

ข้อผิดพลาดด้านความปลอดภัยมากขึ้น - อีกหนึ่งข้อผิดพลาดที่คุณอาจไม่ต้องแก้ไข

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

ถ้าฉันมีหนึ่งซับฉันมักจะจัดรูปแบบดังต่อไปนี้:

if( some_condition ) { do_some_operation; }

หากบรรทัดนั้นยุ่งยากเกินไปให้ใช้วิธีต่อไปนี้:

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