it-swarm-vi.com

Tuyên bố đơn nếu khối - niềng răng hay không?

Cái nào tốt hơn/thường được chấp nhận hơn?

Điều này:

if(condition)
{
  statement;
}

Hoặc là:

if(condition)
  statement;

Tôi có xu hướng thích cái đầu tiên hơn, bởi vì tôi nghĩ nó dễ dàng hơn để nói cái gì thực sự thuộc về khối if, nó sẽ cứu người khác khỏi việc niềng răng sau (hoặc tạo ra một lỗi bằng cách quên) và nó tạo ra tất cả các câu lệnh if của bạn đồng phục thay vì một số có niềng răng và một số không có. Tuy nhiên, cái thứ hai vẫn đúng về mặt cú pháp và chắc chắn gọn hơn. Tôi tò mò muốn xem cái nào thường được người khác ưa thích hơn.

59
Zann Anderson

Thứ nhất là tốt hơn bởi vì thứ hai là dễ bị lỗi. Ví dụ: giả sử bạn đang tạm thời nhận xét mã để gỡ lỗi một cái gì đó:

if(condition) 
//      statement;
otherStatement;

Hoặc thêm mã vội vàng:

if(condition) 
    statement;
    otherStatement;

Điều này rõ ràng là xấu. Mặt khác, đôi khi người đầu tiên cảm thấy quá dài dòng. Do đó, tôi thích chỉ đặt mọi thứ trên một dòng nếu nó đủ ngắn và đơn giản:

if(condition) statement;

Điều này cắt giảm tiếng ồn cú pháp trong khi làm cho cấu trúc trông giống như những gì nó thực sự làm, làm cho nó ít bị lỗi hơn. Với điều kiện cú pháp này chỉ được sử dụng cho các điều kiện và câu lệnh rất đơn giản, ngắn gọn, tôi thấy nó hoàn toàn dễ đọc.

131
dsimcha

Tôi luôn luôn sử dụng dấu ngoặc chỉ để an toàn.

Sẽ ổn khi bạn viết nó, nhưng bạn biết ai đó sẽ xuất hiện trong tương lai và chèn một tuyên bố khác mà không đặt dấu ngoặc quanh nó.

44
Neil Aitken

Tôi thích phiên bản không có dấu ngoặc nếu có thể.

Giải thích sau đây là dài dòng. Xin vui lòng chịu với tôi. Tôi sẽ đưa ra một lý do thuyết phục để tôi thích phong cách này. Tôi cũng sẽ giải thích lý do tại sao tôi nghĩ rằng các đối số thông thường không nắm giữ.

(Gần-) các dòng trống là một sự lãng phí

Lý do cho điều này là vì dấu ngoặc đóng yêu cầu thêm một dòng mã - và dấu ngoặc mở cũng vậy, tùy thuộc vào kiểu dáng.1

Đây có phải là một vấn đề lớn? Bề ngoài, không. Rốt cuộc, hầu hết mọi người cũng đặt các dòng trống trong mã của họ để tách các khối độc lập một chút về mặt logic, giúp cải thiện đáng kể khả năng đọc.

Tuy nhiên, tôi ghét lãng phí không gian dọc. Màn hình hiện đại thực sự có không gian ngang rộng rãi. Nhưng dọc không gian vẫn còn rất, rất hạn chế (trừ khi bạn sử dụng màn hình được đặt thẳng đứng, đó là điều không phổ biến). Không gian dọc hạn chế này is một vấn đề: phải thừa nhận rộng rãi rằng các phương thức riêng lẻ phải càng ngắn càng tốt và các dấu ngoặc tương ứng (hoặc các dấu phân cách khối khác) không chênh lệch chiều cao màn hình để bạn có thể nhìn thấy toàn bộ khối mà không cần cuộn.

Đây là một vấn đề cơ bản: một khi bạn có thể nhìn thấy toàn bộ khối trên màn hình của mình nữa, việc nắm bắt sẽ trở nên phức tạp.

Kết quả là, tôi ghét sự trống rỗng dư thừa. Trong đó các dòng trống đơn rất quan trọng để phân định các khối độc lập (chỉ cần nhìn vào hình thức trực quan của văn bản này), liên tiếp các dòng trống là a rất kiểu xấu trong tôi cuốn sách (và theo kinh nghiệm của tôi chúng thường là một dấu hiệu của những lập trình viên mới làm quen).

Tương tự như vậy, các dòng chỉ đơn giản là giữ một cú đúp, và có thể được tiết kiệm, nên được. Một khối lệnh đơn được phân định bằng dấu ngoặc sẽ lãng phí một đến hai dòng. Chỉ với 50 dòng trên mỗi chiều cao màn hình, điều này là đáng chú ý.

Bỏ niềng răng có thể không có hại

Chỉ có one đối số bỏ qua dấu ngoặc nhọn: sau đó ai đó sẽ thêm một câu lệnh khác vào khối được đề cập và sẽ quên thêm dấu ngoặc, do đó vô tình thay đổi ngữ nghĩa của mã.

Đây thực sự sẽ là một vấn đề lớn.

Nhưng theo kinh nghiệm của tôi, nó không phải là. Tôi là một lập trình viên cẩu thả; Tuy nhiên, trong thập kỷ kinh nghiệm lập trình của mình, tôi có thể thành thật nói rằng tôi có không chỉ một lần quên thêm dấu ngoặc nhọn khi thêm một câu lệnh bổ sung vào khối đơn.

Tôi thậm chí còn thấy rằng đây là một lỗi phổ biến: các khối là một phần cơ bản của lập trình. Độ phân giải cấp độ khối và phạm vi là một quá trình tinh thần tự động, ăn sâu cho các lập trình viên. Bộ não chỉ làm điều đó (nếu không, lý luận về lập trình sẽ khó hơn nhiều). Không có nỗ lực tinh thần bổ sung cần thiết để ghi nhớ việc niềng răng: sau đó, lập trình viên cũng nhớ thụt lề câu lệnh vừa được thêm chính xác; Vì vậy, lập trình viên đã xử lý tinh thần rằng một khối có liên quan.

Bây giờ, Tôi là không nói rằng bỏ qua niềng răng không gây ra lỗi. Điều tôi đang nói là chúng tôi không có bằng chứng theo cách này hay cách khác. Chúng tôi chỉ đơn giản không biết liệu điều đó có gây hại hay không.

Vì vậy, cho đến khi ai đó có thể chỉ cho tôi dữ liệu cứng, được thu thập từ các thí nghiệm khoa học, chứng minh rằng đây thực sự là một vấn đề trong thực tế, lý thuyết này vẫn là một câu chuyện đơn giản : một giả thuyết rất hấp dẫn chưa từng có đưa vào thử nghiệm và điều đó phải không được sử dụng làm đối số.


1 Vấn đề này đôi khi được giải quyết bằng cách đặt mọi thứ - bao gồm cả niềng răng - trên cùng một dòng:

if (condition)
{ do_something(); }

Tuy nhiên, tôi tin rằng nó rất an toàn khi nói rằng hầu hết mọi người đều coi thường điều này. Hơn nữa, nó sẽ có những vấn đề tương tự như biến thể không có niềng răng, vì vậy nó là điều tồi tệ nhất của cả hai thế giới.

27
Konrad Rudolph

Tôi đi với cái thứ hai. Nó ngắn gọn hơn và ít dài dòng hơn.

Tôi cố gắng không viết cho mẫu số chung thấp nhất, vì vậy tôi hy vọng rằng các nhà phát triển khác biết cách viết một trong những cấu trúc luồng điều khiển phổ biến nhất trong lập trình hiện nay.

19
Steven Evers

Tôi sẽ sử dụng như sau (sự đồng thuận ở đây):

if (condition) {
    any_number_of_statements;
}

Cũng có thể:

if(condition) single_compact_statement;

Không tốt lắm, đặc biệt là trong C/C++ - như các ngôn ngữ:

if(condition) 
    single_compact_statement;

(Không có lựa chọn nào ở đây trong Python ;-)


Trong Perl , bạn sẽ sử dụng:

$C = $A**3 if $A != $B;

hoặc là

$C = $A**3 unless $A == $B;

(Đây là không mã giả ;-)

16
rubber boots

Tôi sử dụng phương pháp niềng răng - vì tất cả các lý do trên cộng thêm một lý do nữa.

Mã hợp nhất. Điều này đã được biết là xảy ra đối với các dự án mà tôi đã làm việc trên các câu lệnh đơn đó đã bị phá vỡ bởi sự hợp nhất tự động. Điều đáng sợ là vết lõm có vẻ ngay cả khi mã bị sai, vì vậy loại lỗi này rất khó phát hiện.

Vì vậy, tôi đi với niềng răng - trên dòng riêng của họ. Nó dễ dàng hơn để phát hiện các cấp theo cách đó. Vâng, nó lãng phí bất động sản màn hình dọc và đó là một nhược điểm thực sự. Về cân bằng, tôi nghĩ rằng nó có giá trị nó.

11
user36294

Không niềng răng. Nếu một số lập trình viên khác thêm một câu lệnh thứ hai vào mã của tôi thì đó không phải là lỗi của tôi hơn là nếu tôi để ai đó lái xe của mình và họ đi qua một vách đá.

10
Covar

Chúng tôi đã có tranh luận này hơn một lần ở đây và sự đồng thuận chung là luôn luôn sử dụng niềng răng. Những lý do chính là về khả năng đọc/bảo trì.

Nếu bạn cần thêm mã vào khối if, bạn không cần phải nhớ/tìm kiếm dấu ngoặc nhọn. Khi các lập trình viên tương lai đọc mã, các dấu ngoặc nhọn luôn không rõ ràng.

Về mặt tích cực, ReSharper sẽ tự động thêm dấu ngoặc nhọn cho các lập trình viên lười biếng trong Visual Studio và tôi cho rằng có các addon cho IDE cũng sẽ làm như vậy.

8
shimonyk

Tôi sử dụng cú pháp đầu tiên, gần như không có ngoại lệ. Bởi vì không thể giải thích sai.

"Đừng khiến tôi phải suy nghĩ" không chỉ áp dụng cho giao diện người dùng, vì vậy ;-)

7
Steven A. Lowe

Cá nhân tôi thích thứ hai. Cái đầu tiên trông xấu xí, vụng về và lãng phí không gian ngang. Các vấn đề chính với cái thứ hai là macro và mọi người sửa đổi mã của bạn tại một thời điểm sau đó đã bị sai.

Về điều này, tôi nói "không sử dụng macro". Tôi cũng nói, "thụt chính xác mã chết tiệt của bạn". Xem xét cách mọi trình soạn thảo văn bản/IDE được sử dụng để lập trình tự động thụt lề, điều này không khó thực hiện. Khi viết mã bằng Emacs, tôi sẽ sử dụng thụt lề tự động để xác định xem tôi có viết sai gì trên dòng trước không. Bất cứ khi nào Emacs bắt đầu vặn vẹo thụt, tôi thường biết mình đã làm gì đó sai.

Trong thực tế, tôi kết thúc theo bất kỳ quy ước mã hóa nào đã được đặt ra trước tôi. Nhưng những điều này làm tôi khó chịu (và khiến tôi hạnh phúc hơn nhiều khi tôi viết mã Python và toàn bộ thảm họa khung này đã biến mất):

if (condition) {
    statement;
} // stupid extra brace looks ugly

Sau đó

if (condition) // the brackets have now just become noise
{ statement; } // also can't see the indentation, harder to read

Mặc dù thành thật mà nói, hai câu trong một câu lệnh if làm tôi khó chịu hơn nhiều so với một câu lệnh. Chủ yếu là vì sau đó dấu ngoặc là bắt buộc và nó vẫn trông buồn cười chỉ với hai câu lệnh trong câu lệnh if.

5
jsternberg

Tôi sử dụng phiên bản hai dòng không có dấu ngoặc (dạng thứ 2), nhưng không để tiết kiệm dung lượng.

Tôi sử dụng hình thức đó bởi vì tôi thấy nó dễ đọc hơn, hấp dẫn hơn và dễ gõ hơn. Tôi chỉ sử dụng hình thức đó nếu những điều kiện đó được đáp ứng; tức là điều kiện if phải vừa vặn trên một dòng duy nhất và câu lệnh tương ứng phải phù hợp độc đáo trên dòng sau. Nếu đó không phải là trường hợp, thì tôi sẽ sử dụng niềng răng để cải thiện khả năng đọc.

Nếu tôi sử dụng biểu mẫu này, tôi chắc chắn rằng có một dòng trống (hoặc một dòng chỉ chứa một dấu ngoặc) trước và sau câu lệnh if (hoặc trên nhận xét, nếu có). Mặc dù đây không phải là một quy tắc mà tôi có ý thức tuân theo, tôi nhận thấy nó ngay bây giờ sau khi đọc câu hỏi này.

Bảo tồn không gian màn hình không phải là ưu tiên hàng đầu của tôi. Nếu tôi cần thêm không gian, tôi sẽ sử dụng màn hình lớn hơn. Màn hình của tôi đủ lớn để tôi có thể đọc bất cứ thứ gì mà tôi có thể cần tập trung chú ý vào. Không chắc là tôi sẽ cần phải tập trung vào rất nhiều dòng mã cùng một lúc mà chúng chiếm toàn bộ màn hình của tôi. Nếu có quá nhiều lồng nhau xảy ra với một đoạn mã mà tôi không thể hiểu nó mà không xem nhiều hơn một lần, thì tôi sẽ phải xem xét liệu logic có thể được biểu diễn tốt hơn bằng cách tái cấu trúc hay không.

Dưới đây là một số ví dụ minh họa cách tôi sử dụng mẫu câu lệnh if này.

    string GuardConditions(Plan planForWorldDomination)
    {
        if (planForWorldDomination == null)
            throw new ArgumentNullException("planForWorldDomination");

        if (!planForWorldDomination.IsComplete())
            return "Doh!";

        planForWorldDomination.Execute();
    }

    void ProcessingLogic()
    {
        OneBlankLineAbove();

        if (simpleCondition)
            simpleStatement();

        OneBlankLineBelow();
        OneBlankLineAbove();

        // optional comment on the line above an if statement
        if (simpleCondition)
            simpleStatement();

        OneBlankLineBelow();
    }

    void Assignment(string drive)
    {
        OneBlankLineAbove();

        string Prompt;
        if (simpleCondition)
            Prompt = "simple assignment";
        else
            Prompt = null;

        OneBlankLineBelow();
    }

    string Return()
    {
        OneBlankLineAbove();

        if (simpleCondition)
            return "simple return";
        else
            return null;

        OneBlankLineBelow();
    }
4
Dr. Wily's Apprentice

Niềng răng. Luôn luôn. Tôi là fan hâm mộ của họ, bởi vì nó mang lại cho sự nhất quán mã. Và cũng như @dsimcha đã viết - ít có khả năng xảy ra lỗi khi thêm các dòng mã bổ sung.

"Ugliness" của dấu ngoặc nhọn xung quanh một dòng mã ít gây hại hơn công việc bổ sung có thể xảy ra trong những trường hợp có gỡ lỗi và/hoặc thêm mã.

3
Vedran Krivokuća

Cá nhân tôi đi với dấu ngoặc.

Tại sao?

Chà, nếu có ai đi cùng và cần thêm mã vào câu lệnh if thì rõ ràng 100% phạm vi nằm ở đâu.

Nó giữ định dạng của các câu lệnh if cho dù có bao nhiêu câu lệnh trong khối.

Tuy nhiên, nếu phong cách dự án là đi mà không có, hãy bám vào đó.

2
ChrisF

Tôi hầu như luôn luôn sử dụng dấu ngoặc chỉ để ở bên an toàn. Tuy nhiên, đôi khi nếu nội dung của khối thực sự ngắn thì tôi sẽ bỏ chúng đi và biến nó thành một lớp lót như vậy:

if (x==5) Console.WriteLine("It's a five!");
1
JohnFx

Tôi thích niềng răng vì tính nhất quán, nhưng không lãng phí quá nhiều khoảng trắng (vì vậy mã được định dạng dễ đọc hơn nằm trong trường nhìn hạn chế của tôi). Vì vậy, tôi viết điều này cho các dòng đủ ngắn:

If (cond) { statement; }
1
hotpaw2

Tôi thường sử dụng niềng răng, nhưng có một số trường hợp tôi không dùng.

object GetObject() {
    // calculate obj1
    if(obj1 != null)
        return obj1;

    // calculate obj2
    if(obj2 != null)
        return obj2;

    // calculate obj3
    if(obj3 != null)
        return obj3;

    return defaultObj;
}

Đối với tôi, thật là ngớ ngẩn khi thêm chúng ở đó. Nếu ai đó thêm một tuyên bố sau return, chúng tôi có vấn đề lớn hơn các vấn đề phạm vi.

Nếu IDE có định dạng mã có sẵn, tôi không sử dụng dấu ngoặc nhọn.

Mặt khác, nơi mã có thể được chỉnh sửa trong các trình soạn thảo khác không hỗ trợ định dạng tự động, thật nguy hiểm nếu không đặt dấu ngoặc nhọn như được đề cập trong các bài đăng khác. Nhưng ngay cả như vậy tôi không thích sử dụng niềng răng, và nó không phải là vấn đề đối với tôi.

0
nimcap