กรณีสวิตช์ Java: มีหรือไม่มีวงเล็บปีกกา?


86

พิจารณาสองตัวอย่างต่อไปนี้โดยใช้วงเล็บปีกกา:

switch (var) {
  case FOO: {
    x = x + 1;
    break;
  }

  case BAR: {
    y = y + 1;
    break;
  }
}

โดยไม่ต้องจัดฟัน:

switch (var) {
  case FOO:
    x = x + 1;
    break;

  case BAR:
    y = y + 1;
    break;
}

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

คำตอบ:


100

มีโทษด้านประสิทธิภาพการใช้เครื่องมือจัดฟันกับเคสหรือไม่?

ไม่มี.

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


21

ไม่มีการลงโทษประสิทธิภาพจากมุมมองของการดำเนินการ

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

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


สงสัยนิดนึงเพราะยังหาคำตอบไม่ได้ ... @TofuBeer ต้องจัดฟันตอนไหน นอกจากนี้ฉันเห็นด้วยอย่างยิ่งกับประเด็นการบำรุงรักษาฉันไม่เห็นปัญหาการบำรุงรักษา ATM แก้ไข: ไม่เป็นไร ฉันเพิ่งอ่านคำตอบที่เหลือด้านล่างนี้
nyaray

คุณทำใน C ++ ในบางกรณีดังนั้นหากคุณทำงานในทั้งสองภาษาก็ไม่ใช่นิสัยที่ไม่ดีที่จะเข้ามาเช่นกัน
TofuBeer

13

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

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

เช่นเมื่อฉันมีสิ่งที่ชอบ

switch(i)
{
  case 1 :
  {
     //do something
  }
  System.out.println("Hello from 1");

  case 2: 
  ....
}

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

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

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

คำแนะนำของฉัน: เพียงหลีกเลี่ยงการใช้วงเล็บปีกกาโดยรอบเพื่อเปลี่ยนเคส


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

เครื่องมือจัดฟันมีไว้เพื่อป้องกันสถานการณ์ที่คุณพูดถึงในตัวอย่างของคุณ ...
Petr Dvořák

12

ด้วยเครื่องมือจัดฟัน

มีหลายสิ่งหลายอย่างที่อาจผิดพลาดกับคำสั่ง switch ฉันพยายามหลีกเลี่ยงสิ่งเหล่านี้ในที่ที่ทำได้เช่น

  1. ลืมการหยุดพักและทำให้เกิดกรณีตก
  2. ลืมกรณีที่เป็นค่าเริ่มต้นจึงไม่พบเงื่อนไขที่ไม่รองรับ
  3. การนำตัวแปรมาใช้ซ้ำโดยไม่ได้ตั้งใจระหว่างคำสั่ง case หรือแย่กว่านั้นก็ส่งผลต่อตัวแปรที่ IS แชร์ตัวแปรระหว่าง case statement

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


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

จุดที่ 3 ไม่สมเหตุสมผลด้วยซ้ำ คุณไม่สามารถใช้ตัวแปรซ้ำได้เว้นแต่จะประกาศไว้ในขอบเขตหลักของคำสั่ง switch ซึ่งหมายความว่าหากคุณประกาศตัวแปรภายในเคสจะไม่สามารถใช้ในคำสั่ง case อื่นได้ หากคุณประกาศตัวแปรเหนือคำสั่ง switch (ในขอบเขตหลัก) ก็ไม่สำคัญว่าคุณจะใช้เครื่องหมายวงเล็บปีกกาหรือไม่คำสั่ง case จะสามารถเข้าถึงตัวแปรได้
dsingleton

ฉันเพิ่งค้นพบว่าตัวแปรที่ประกาศในกรณีที่ 1 ยังคงอยู่ในขอบเขตในกรณีที่ 2 เช่น: ...case 1: int a = 10; break; case 2: int a = 11; break; ...ไม่ได้รวบรวม (ทดสอบด้วย Oracle JDK 8)
anuragw

5

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


ฉันเดาว่ามันเป็นคำถามที่มีวัตถุประสงค์ ... ฉันถอนสิ่งที่โต้แย้ง
Andy White

ฉันชอบมันโดยไม่ต้องจัดฟัน ... ฉันพบว่าเครื่องมือจัดฟันทำให้เกิดเสียงที่ไม่จำเป็นมากมาย
cdmckay

ใช่ฉันหวังว่ามันจะเป็นแบบนี้มากกว่านี้ case (FOO) {x = x + 1} case (BAR) {y = y + 1}
Andy White

ช่องว่างที่เหมาะสม == ดี จัดฟันโดยไม่จำเป็น == ดูด.
Shog9

3
whitespace == การผสมผสานของแท็บและช่องว่าง == ดูด (แค่คิดว่าฉันจะโยนแท็บเทียบกับช่องว่างความคิดเห็นลงในส่วนผสม)
Andy White

5

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

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


3

ฉันจะไม่ใช้วงเล็บปีกกาสำหรับเคสสวิตช์

  • คำสั่งสวิตช์ดูพิสดารพอโดยไม่ต้องจัดฟัน

  • กรณีการสลับควรสั้นมาก เมื่อคุณต้องการประกาศตัวแปรเป็นสัญญาณว่าคุณทำผิด

ตอนนี้ออกไปเพื่อรักษารหัส C ดั้งเดิมซึ่งสลับกรณีกีฬา 500+ บรรทัด ...


1

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

ไม่มีวงเล็บ ... ไวยากรณ์น้อยกว่ามาก


{and} ทำให้สิ่งต่างๆโดดเด่นเช่นกันซึ่งทำให้อ่านง่ายขึ้น (IMO)
TofuBeer

ได้. ฉันจะแบ่งปันเรื่องราวของวิธีการที่ฉันเคยแก้ไขครั้งหนึ่ง (ฉันใช้เวลาประมาณ 4 ชั่วโมงในการเพิ่มโค้ดหนึ่งบรรทัด) แต่โค้ดนั้นบ้า (ยาวประมาณ 10 หน้าและกว้าง 4 หน้าเมื่อพิมพ์) ดังนั้นจึงไม่ใช่ กรณีทั่วไป แต่หากมีการใช้งาน {} จะต้องใช้เวลาสักครู่ในการเพิ่ม
TofuBeer

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

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