Có ổn không nếu tôi bỏ qua dấu ngoặc nhọn trong Java? [đóng cửa]


83

Tôi đã tìm kiếm điều này, nhưng không thể tìm thấy câu trả lời và vì lý do gì đó, tôi quá xấu hổ khi hỏi giáo sư, vì cảm giác đó khi hàng trăm người nhìn chằm chằm vào bạn ...

Nhưng dù sao, câu hỏi của tôi là tầm quan trọng của việc có dấu ngoặc là gì? Có ổn không nếu tôi bỏ qua chúng? Thí dụ:

for (int i = 0; i < size; i++)  {
   a += b;
}

vs

for (int i = 0; i < size; i++)
   a += b;

Tôi biết cả hai đều sẽ hoạt động, nhưng nếu tôi bỏ dấu ngoặc (mà tôi có xu hướng làm rất nhiều, do khả năng hiển thị) thì điều đó có thay đổi bất cứ điều gì không? Như tôi đã nói, tôi biết nó hoạt động, tôi đã thử nghiệm nó hàng chục lần, nhưng bây giờ một số bài tập đơn lẻ của tôi ngày càng lớn hơn, và vì lý do nào đó tôi lo sợ rằng về lâu dài, điều này gây ra một số vấn đề? Có lý do gì để sợ điều đó?


Tôi luôn sử dụng một trình định dạng mã để dễ đọc vì điều này giải quyết được nhiều nguyên nhân tiềm ẩn gây nhầm lẫn. Điều này có thể làm cho sử dụng xoăn ngoặc dư thừa
Peter Lawrey

Câu trả lời:


146

Nó sẽ không thay đổi bất cứ điều gì ngoài khả năng bảo trì mã của bạn. Tôi đã thấy mã như thế này:

for (int i = 0; i < size; i++)
   a += b;
   System.out.println("foo");

có nghĩa là:

for (int i = 0; i < size; i++)
   a += b;
System.out.println("foo");

... nhưng lẽ ra phải là cái này:

for (int i = 0; i < size; i++) {
   a += b;
   System.out.println("foo");
}

Cá nhân tôi luôn bao gồm các dấu ngoặc để giảm khả năng nhầm lẫn khi đọc hoặc sửa đổi mã.

Các quy ước mã hóa tại mọi công ty tôi từng làm việc đều yêu cầu điều này - điều này không có nghĩa là một số công ty khác không có các quy ước khác ...

Và đề phòng trường hợp bạn nghĩ rằng nó sẽ không bao giờ tạo ra sự khác biệt: Tôi đã phải sửa một lỗi một lần khá tương đương với đoạn mã trên. Rất khó phát hiện ra nó ... (phải thừa nhận đây là năm trước, trước khi tôi bắt đầu thử nghiệm đơn vị, điều này chắc chắn sẽ giúp chẩn đoán dễ dàng hơn).


12
@vedran: Vậy là bạn đã biết về vấn đề này nhưng bạn chỉ cho rằng nó sẽ không bao giờ cắn bạn? Và rằng mọi người đọc mã của bạn sẽ biết điều gì sẽ xảy ra? Tôi chỉ nói rằng - có một lý do tại sao họ đang yêu cầu trong công ước mã hóa Tôi đã làm việc với :)
Jon Skeet

12
Tôi chỉ cảm thấy như một chuyện riêng tư bị nói chuyện bởi một sarge. Có, trong khi nó thuận tiện hơn cho tôi, những người khác trong nhóm của tôi, tôi thấy nó phiền phức và có vấn đề. Tôi sẽ đảm bảo sử dụng dấu ngoặc ở mọi nơi kể từ bây giờ.
vedran

13
@vedran ẩn dụ tốt đẹp, ngoại trừ Jon Skeet không phải là sarge, anh ấy là tổng chỉ huy :-)
stivlo

5
@stivlo Ồ, tôi chắc chắn rằng ân huệ của anh ấy sẽ tha thứ cho sự bất tuân nhỏ;) Cá nhân tôi đặt dấu ngoặc sau các tuyên bố, vì đó là một phần của mọi hướng dẫn viết mã mà tôi từng xem, nhưng tôi nghĩ đó là một lập luận khá yếu hiện nay. Với định dạng mã tự động ở mọi nơi, dù thế nào đi nữa, bạn sẽ không bao giờ thấy mã ở dạng đầu tiên và nếu thụt lề đúng thì dấu ngoặc sẽ không cung cấp thêm thông tin nào.
Voo

4
Đối số khác để sử dụng LUÔN LUÔN dấu ngoặc nhọn: Imperialviolet.org/2014/02/22/applebug.html
MrTJ Ngày

32

Sử dụng dấu ngoặc nhọn làm cho mã dễ bảo trì và dễ hiểu hơn. Vì vậy, bạn nên xem xét chúng theo mặc định .

Đôi khi tôi bỏ qua việc sử dụng dấu ngoặc nhọn trên các mệnh đề bảo vệ để làm cho mã gọn gàng hơn. Yêu cầu của tôi cho điều này là chúng là các ifcâu lệnh được theo sau bởi một câu lệnh nhảy , như returnhoặc throw. Ngoài ra, tôi giữ chúng trên cùng một dòng để thu hút sự chú ý đến thành ngữ, ví dụ:.

if (!isActive()) return;

Chúng cũng áp dụng cho mã bên trong các vòng lặp:

for (...) {
  if (shouldSkip()) continue;
  ...
}

Và các điều kiện nhảy khác từ các phương thức không nhất thiết phải ở đầu thân phương thức.

Một số ngôn ngữ (như Perl hoặc Ruby) có một loại câu lệnh điều kiện , trong đó dấu ngoặc nhọn không áp dụng:

return if (!isActive());
// or, more interestingly
return unless (isActive());

Tôi coi nó tương đương với những gì tôi vừa mô tả, nhưng được ngôn ngữ hỗ trợ một cách rõ ràng.


7
Các mệnh đề bảo vệ +1 bên trong vòng lặp thường rõ ràng hơn mà không có dấu ngoặc nhọn.
Viccari

2
Đồng ý về các điều khoản bảo vệ. Theo ý kiến ​​của tôi, làm cho mã dễ đọc hơn và thực sự tăng khả năng bảo trì. Mặc dù vậy, những điểm mà câu trả lời được chấp nhận tạo ra rất hợp lệ, vì vậy tôi hạn chế việc bỏ qua dấu ngoặc nhọn để bảo vệ các mệnh đề.
ChrisK

11

Không có sự khác biệt. Vấn đề chính với phiên bản thứ hai là bạn có thể viết như sau:

for (...) 
  do_something();
  do_something_else();

khi bạn cập nhật phương thức đó, nghĩ rằng phương thức đó do_something_else()được gọi bên trong vòng lặp. (Và điều đó dẫn đến các phiên gỡ lỗi đau đầu.)

Có một vấn đề thứ hai mà phiên bản dấu ngoặc nhọn không mắc phải và thậm chí còn khó phát hiện hơn:

for (int i=0; i<3; i++);
  System.out.println("Why on earth does this print just once?");

Vì vậy, hãy giữ lại niềng răng trừ khi bạn có lý do chính đáng, nó chỉ là một vài lần gõ phím nữa.


3
Điểm đầu tiên là tốt, nhưng điểm thứ hai là sai. Phiên bản niềng răng vẫn có thể có vấn đề đó. for (int i = 0; i <3; i ++); {System.out.println ("Tại sao điều này chỉ in một lần?"); }. Tôi biết vì tôi luôn sử dụng dấu ngoặc nhọn, nhưng đôi khi thêm sai dấu chấm phẩy.
emory

3
Phiên bản dấu ngoặc nhọn có thể có nó, nhưng sẽ rõ hơn nếu dấu ngoặc nhọn nằm trên cùng một đường thẳng. Với dấu ngoặc nhọn ở dòng tiếp theo, quả thực, nó khá tệ hại.
Mat

Phiên bản thứ hai đối với tôi cũng quan trọng như phiên bản đầu tiên, bởi vì nhìn vào phiên bản thứ hai, hầu như không thể phát hiện ra điều gì sai cho đến khi bạn thực sự chạy nó để xem điều gì đang xảy ra trên thế giới. Các nhà phát triển dành nhiều thời gian để gỡ lỗi mã như thế này, điều này sẽ dễ dàng bị phát hiện nếu những dấu ngoặc nhọn đó được giới thiệu. Đối với tôi, việc bỏ qua những dấu ngoặc vuông vức đó không chỉ là vấn đề về phong cách mà là một chỉ báo tốt về mã lỗi có thể xảy ra.
theyCallMeJun

5

Tôi nghĩ rằng việc loại bỏ dấu ngoặc nhọn là tốt, nếu bạn cũng đang sử dụng định dạng tự động, bởi vì thụt lề của bạn luôn đúng, vì vậy sẽ dễ dàng phát hiện ra bất kỳ lỗi nào theo cách đó.

Nói rằng bỏ dấu ngoặc nhọn là xấu, kỳ lạ hoặc khó đọc là sai, vì toàn bộ ngôn ngữ đều dựa trên ý tưởng đó và nó khá phổ biến (python).

Nhưng tôi phải nói rằng nếu không sử dụng bộ định dạng thì nó có thể nguy hiểm.


Vấn đề thụt lề trong Python. Trong Java, C, C ++ hoặc các ngôn ngữ kiểu C khác thì không.
Christopher Schneider

1
@ChristopherSchneider Đó là sự bình tĩnh.
Máté Magyar

5

Đối với hầu hết các trường hợp, các câu trả lời được đề cập cho đến nay đều đúng. Nhưng có một số nhược điểm đối với nó từ góc độ bảo mật của mọi thứ. Đã từng làm việc trong nhóm thanh toán, bảo mật là một yếu tố mạnh mẽ hơn nhiều thúc đẩy các quyết định như vậy. Giả sử bạn có mã sau:

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )

Bây giờ giả sử bạn có mã này không hoạt động do một số vấn đề nội bộ. Bạn muốn kiểm tra đầu vào. Vì vậy, bạn thực hiện thay đổi sau:

if( "Prod".equals(stage) )
  callBankFunction ( creditCardInput )
else
  callMockBankFunction ( creditCardInput )
  Logger.log( creditCardInput )

Giả sử bạn khắc phục sự cố và triển khai mã này (và có thể người đánh giá & bạn nghĩ rằng điều này sẽ không gây ra sự cố vì nó không nằm trong điều kiện 'Sản phẩm'). Thật kỳ diệu, nhật ký sản xuất của bạn giờ đây in thông tin thẻ tín dụng của khách hàng hiển thị cho tất cả nhân viên có thể xem nhật ký. Xin Chúa cấm nếu bất kỳ ai trong số họ (với mục đích xấu) nắm giữ dữ liệu này.

Do đó, việc không cung cấp dấu ngoặc nhọn và một chút mã hóa bất cẩn thường có thể dẫn đến vi phạm thông tin an toàn. Nó cũng được phân loại là một lỗ hổng trong JAVA bởi CERT - Tổ chức Kỹ thuật Phần mềm, CMU .


Tôi cho rằng đó là một thiết kế khá khủng khiếp ngay từ đầu, nhưng quan điểm là hợp lệ.
Christopher Schneider

4

Nếu bạn có một câu lệnh duy nhất, bạn có thể bỏ qua các dấu ngoặc, vì vậy một câu lệnh trong ngoặc là cần thiết để khai báo một khối mã.

Khi bạn sử dụng dấu ngoặc, bạn đang khai báo một khối mã:

{

//Block of code
}

Chỉ nên sử dụng dấu ngoặc với một câu lệnh khi bạn ở trong tình huống câu lệnh lồng nhau để cải thiện khả năng đọc, ví dụ:

for( ; ; )
  if(a == b) 
    doSomething()

nó cũng dễ đọc hơn được viết bằng dấu ngoặc nếu không cần thiết:

for( ; ; ) {
  if(a == b) {
    doSomething()
   }
}

4

Nếu bạn sử dụng dấu ngoặc, mã của bạn dễ đọc hơn. Và nếu bạn cần thêm một số toán tử trong cùng một khối, bạn có thể tránh các lỗi có thể xảy ra


3

Sử dụng dấu ngoặc trong tương lai chứng minh mã chống lại các sửa đổi sau này. Tôi đã gặp trường hợp dấu ngoặc bị bỏ qua và sau đó ai đó đã thêm một số mã và không đặt dấu ngoặc vào lúc đó. Kết quả là đoạn mã mà họ thêm vào không đi vào phần mà họ cho là có. Vì vậy, tôi nghĩ câu trả lời là thực tiễn tốt của nó dựa trên những thay đổi trong tương lai đối với mã. Tôi đã thấy các nhóm phần mềm áp dụng tiêu chuẩn đó, tức là luôn yêu cầu dấu ngoặc ngay cả với các khối dòng đơn vì lý do đó.


Tôi đồng ý với điều này. Dấu ngoặc không dành cho bạn. Chúng dành cho người đến sau bạn. Một vài lần, tôi có mã mà tôi đang duy trì mà tôi không quen thuộc với mã không sử dụng dấu ngoặc và có thụt lề kém. Ở giai đoạn này, tôi có thể đang sửa một lỗi, vì vậy thật tốt khi biết điều gì sẽ xảy ra. Bỏ qua niềng răng làm cho nó ít rõ ràng hơn, và tôi phải bước qua mã, lãng phí thời gian.
Christopher Schneider

2

Hỗ trợ thêm cho nhóm "luôn niềng răng" từ tôi. Nếu bạn bỏ qua dấu ngoặc nhọn cho các vòng lặp / nhánh câu lệnh đơn, hãy đặt câu lệnh trên cùng dòng với câu lệnh điều khiển,

if (condition) doSomething();
for(int i = 0; i < arr.length; ++i) arr[i] += b;

theo cách đó, sẽ khó quên việc lắp mắc cài khi cơ thể được mở rộng. Tuy nhiên, dù sao đi nữa, hãy sử dụng những đường cong.


2

sử dụng dấu ngoặc nhọn thừa để tuyên bố rằng mã dễ bảo trì hơn đặt ra câu hỏi sau: nếu những người đang viết, băn khoăn và tiếp tục duy trì mã có vấn đề như những gì được mô tả trước đây (liên quan đến thụt lề hoặc liên quan đến khả năng đọc) có lẽ họ không nên lập trình chút nào .. .


1

Kết quả khôn ngoan, nó là một điều tương tự.

Chỉ có hai điều cần xem xét.

- Khả năng bảo trì mã - Mã được
ghép nối lỏng lẻo. (có thể thực thi một cái gì đó khác. bởi vì bạn chưa chỉ định phạm vi cho vòng lặp.)

Lưu ý: Theo quan sát của tôi, nếu nó là vòng lặp với trong một vòng lặp. Vòng trong không mắc cài cũng an toàn. Kết quả sẽ không thay đổi.


1

Nếu bạn chỉ có một câu lệnh bên trong vòng lặp thì nó giống nhau.

Ví dụ, hãy xem đoạn mã sau:

for(int i=0;i<4;i++)
            System.out.println("shiva");

chúng tôi chỉ có một tuyên bố trong đoạn mã trên. vì vậy không có vấn đề

for(int i=0;i<4;i++)
            System.out.println("shiva");
            System.out.println("End");

Ở đây chúng ta có hai câu lệnh nhưng chỉ câu lệnh đầu tiên đi vào bên trong vòng lặp chứ không phải câu lệnh thứ hai.

Nếu bạn có nhiều câu lệnh trong vòng lặp đơn, bạn phải sử dụng dấu ngoặc nhọn.


1

Nếu bạn tháo niềng răng, nó sẽ chỉ đọc dòng hướng dẫn đầu tiên. Mọi dòng bổ sung sẽ không được đọc. Nếu bạn có nhiều hơn 1 dòng lệnh được thực thi, xin hãy sử dụng dấu ngoặc nhọn - nếu không ngoại lệ sẽ được ném ra.


1

Ngày nay, rất dễ dàng thụt lề mã để tìm ra khối mã nằm trong đó ifhoặc for/ while. Nếu bạn khăng khăng rằng việc thụt lề lại là khó thực hiện, thì dấu ngoặc nhọn đặt ở thụt lề sai có thể khiến bạn bối rối không kém.

for(int i = 0; i < 100; i++) { if(i < 10) {
    doSomething();
} else { for(int j = 0; j < 5; j++) {
        doSomethingElse();
    }
}}

Nếu bạn làm điều này ở mọi nơi, não của bạn sẽ nhanh chóng bị hỏng. Ngay cả với các dấu ngoặc, bạn đang phụ thuộc vào thụt lề để tìm trực quan điểm bắt đầu và kết thúc của các khối mã.

Nếu thụt lề là quan trọng, thì bạn nên viết mã của mình theo đúng thụt lề, vì vậy người khác không cần phải thụt lề lại mã của bạn để đọc chính xác.

Nếu bạn muốn lập luận rằng ví dụ trước là quá giả mạo / cố ý và dấu ngoặc ở đó để giải thích vấn đề thụt lề bất cẩn (đặc biệt là khi bạn sao chép / dán mã), hãy xem xét điều này:

for(int i = 0; i < 100; i++) {
    if(i < 10) {
    doSomething();
}
else {
    for(int j = 0; j < 5; j++) {
        doSomethingElse();
    }
}

Có, nó trông ít nghiêm trọng hơn ví dụ trước, nhưng bạn vẫn có thể bị nhầm lẫn bởi sự thụt lề như vậy.

IMHO, người viết mã có trách nhiệm kiểm tra mã và đảm bảo mọi thứ được thụt vào một cách chính xác trước khi họ tiến hành làm những việc khác.


0

nó cũng phải là một phản xạ để định dạng lại mã ... đó là điều tất nhiên đối với các lập trình viên chuyên nghiệp trong các nhóm chuyên nghiệp


0

Có lẽ tốt nhất bạn nên sử dụng dấu ngoặc nhọn ở mọi nơi vì thực tế đơn giản rằng việc gỡ lỗi này sẽ là một điều cực kỳ phiền toái. Nhưng khôn ngoan khác, một dòng mã không nhất thiết cần dấu ngoặc. Hi vọng điêu nay co ich!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.