Không phải là nếu nếu (0 == giá trị) thì phạm phải làm hại nhiều hơn là tốt? [đóng cửa]


49

Đây là một trong những điều mà tôi ghét nhất khi tôi thấy nó trong mã của người khác. Tôi biết ý nghĩa của nó và tại sao một số người làm theo cách này ("nếu tôi vô tình đặt '=' thì sao?"). Đối với tôi nó rất giống như khi một đứa trẻ đi xuống cầu thang đếm những bước chân thành tiếng.

Dù sao, đây là những lập luận của tôi chống lại nó:

  • Nó phá vỡ dòng chảy tự nhiên của việc đọc mã chương trình. Chúng ta, con người, nói "nếu giá trị bằng 0" chứ không phải "nếu không là giá trị".
  • Trình biên dịch hiện đại cảnh báo bạn khi bạn có một bài tập trong điều kiện của bạn, hoặc thực sự nếu điều kiện của bạn chỉ bao gồm bài tập đó, mà, vâng, trông có vẻ đáng ngờ
  • Bạn không nên quên đặt double '=' khi bạn so sánh các giá trị nếu bạn là lập trình viên. Bạn cũng có thể quên đặt "!" khi kiểm tra không bình đẳng.

17
Tôi cũng không quan tâm lắm đến nó, nhưng nó nằm khá xa trong danh sách cá nhân của tôi về những con thú cưng.
Adam Crossland

7
Và các lập trình viên đôi khi bỏ lỡ đôi '='. Đó là một sai lầm dễ mắc phải và một lỗi rất dễ bỏ qua.
sange

8
Làm thế nào đây không phải là xây dựng hoặc không phải là một câu hỏi thực sự?
TheLQ

7
Điều này đã bị đóng nên đây là ý kiến ​​ngắn gọn của tôi: làm thế nào mọi người có thể nhớ viết 0 == valuenhưng không nhớ viết ==?? Ý tôi là đáng trách, nếu bạn đang nghĩ về nó, tại sao không viết nó một cách chính xác để bắt đầu.
dr Hannibal Lecter

3
@muntoo: Theo trình biên dịch, rất nhiều thứ là "chính xác", tôi không nghĩ đó là một điểm chuẩn rất tốt.
dr Hannibal Lecter

Câu trả lời:


59

À, vâng, "Yoda có điều kiện" ("Nếu không có giá trị, hãy thực thi mã này!"). Tôi luôn chỉ ra bất cứ ai tuyên bố rằng họ "tốt hơn" tại các công cụ như lint (1). Vấn đề đặc biệt này đã được giải quyết từ cuối những năm 70. Hầu hết các ngôn ngữ hiện đại thậm chí sẽ không biên dịch một biểu thức như if(x = 10), vì chúng từ chối ép buộc kết quả của việc gán cho một boolean.

Như những người khác đã nói, nó chắc chắn không phải là một vấn đề, nhưng nó gây ra một chút bất đồng về nhận thức.


32
+1 cho "Điều kiện Yoda". Tôi thực sự đã làm điều đó. :)
Bàn Bobby

3
Trong khi thứ tự là tốt, tôi phản đối so sánh với số 0 thay vì diễn viên boolean đơn giản , if(!value).
SF.

1
Vì vậy, bạn xem xét các bài tập bên trong một điều kiện có lỗi?

4
"Hầu hết các ngôn ngữ hiện đại thậm chí sẽ không biên dịch được điều này" Vấn đề xảy ra khi bạn đang sử dụng một ngôn ngữ âm thầm ép buộc kết quả của việc gán cho một boolean. Ngôn ngữ phổ biến nhất mà tôi có thể nghĩ ra đó là JavaScript. Đây là lý do tại sao tôi luôn sử dụng các điều kiện yoda ngay cả trong Java để tôi không quên làm điều đó khi tôi đang viết javascript. Tôi chuyển đổi giữa hai thường xuyên đủ để nó có thể (và đã) là một vấn đề.
Sam Hasler

3
Có ai biết trình biên dịch sẽ không biên dịch if (0 == x)không?
Kristopher Ives

56

Thật đáng ghét vì nó đánh thuế tinh thần nhỏ, nhưng đáng chú ý.

Mọi người đọc từ trái sang phải trong hầu hết tất cả các ngôn ngữ lập trình (và hầu hết các ngôn ngữ tự nhiên).

Nếu tôi thấy 123 == x, cách tôi phân tích nó là:

  • 123- Vậy thì sao? thông tin không đầy đủ.
  • == - tốt, 123 là 123, tại sao phải kiểm tra nó ...
  • x- ok, vậy đó là những gì chúng tôi quan tâm. Chỉ bây giờ tôi có bối cảnh.
  • Quay trở lại để xem xét lại 123và tại sao x được so sánh với nó.

Khi tôi thấy x == 123phân tích cú pháp tinh thần là:

  • x- Cung cấp bối cảnh, tôi biết những gì điều kiện là về. Tôi có thể chọn bỏ qua phần còn lại. Dựa trên dòng chảy trước đó, tôi có một ý tưởng tốt tại sao và điều gì sẽ đến (và ngạc nhiên nếu nó khác).
  • == - Tôi cũng nghĩ vậy.
  • 123 - Ừ.

Sự gián đoạn là nhỏ (trong một ví dụ đơn giản), nhưng tôi luôn chú ý đến nó.

Đặt giá trị đầu tiên có thể là một ý tưởng tốt nếu bạn muốn thu hút sự chú ý đến nó, ví dụ if (LAUNCH_NUKES == cmd). Thông thường đây không phải là ý định.


5
Chính xác. Trong các ngôn ngữ tự nhiên, hằng số luôn luôn tồn tại sau cùng một lý do: nếu ánh sáng màu đỏ ...
mojuba

2
@mojuba Đúng, nó gần như phổ biến. Điều kỳ lạ là, có một vài ngôn ngữ tự nhiên mà đối tượng đến trước đối tượng (thứ tự OVS / OSV), nhưng tất cả chúng đều tối nghĩa.
dbkk

1
Mặt khác, một số người trong chúng ta có xu hướng đọc các ký hiệu trước biến. Chúng bắt mắt hơn. Vì vậy, tôi sẽ phân tích =hoặc ==trước 123hoặc x, và cuối cùng thậm chí không buồn dịch mã sang tiếng Anh trong đầu.
Izkata

Ngoài ra, hầu hết các trình biên dịch sẽ cảnh báo nếu được nhắc đúng cách, trừ khi người ta sử dụng thêm dấu ngoặc nhọn, vì vậy nó cố gắng giải quyết vấn đề không phải là vấn đề.
Ded repeatator

47

Có hại không? Không. Nó hoạt động theo cách nào đó.

Thực hành xấu? Tranh cãi, tốt nhất. Đó là chương trình phòng thủ đơn giản.

Đáng để mất ngủ hơn? Không


8
Và khi tôi đọc nó, tôi hiểu mã ngay lập tức đó là lý do quan trọng nhất để tranh luận về một phong cách mã hóa. Tôi hoàn toàn đồng ý, không đáng để mất ngủ hơn.
Jeff Siver

17

Điều này về cơ bản là flaimbait.

Không, nó không gây hại nhiều hơn là tốt. Đơn giản.

Thêm nhiều từ ngữ?

Trình biên dịch đối số? Erm, ish, có lẽ - đừng đặt quá nhiều niềm tin vào người khen để cứu bạn khỏi chính bạn.

"Bạn không nên quên" - duh - dĩ nhiên là bạn không nên mệt mỏi, tôi đã viết mã cả ngày tôi phải sử dụng hai ngôn ngữ khác nhau và đôi khi, đôi khi, chỉ là con người tôi tạo ra một sai lầm.

Điểm quan trọng của loại hành vi này là sự phòng thủ của nó, nó không ở đó bởi vì bạn dự kiến ​​sẽ phạm sai lầm nhiều hơn bạn có bảo hiểm vì bạn sẽ gặp sự cố ... nhưng nếu bạn làm điều đó thật tốt để được bảo vệ.

Khó để đọc? Bạn đang phàn nàn rằng một lập trình viên đàng hoàng nên có == hardwired (điều này làm cho tất cả các loại giả định kém) nhưng rằng lập trình viên tương tự cũng không thể đọc 0 == value ??

Không có hại, có lợi ích tiềm năng, câu hỏi ngớ ngẩn, hãy để người khác làm điều đó nếu họ muốn và tiếp tục.


6
Tôi nghĩ 0 == giá trị đọc không tự nhiên đối với những người nghiên cứu đại số trước khi họ học lập trình.
mojuba

4
Đó không phải là vấn đề - vâng, bạn nói đúng, nó không đọc đúng nhưng cũng rất nhiều những gì chúng tôi, với tư cách là lập trình viên, viết không chính xác xếp chồng lên nhau như ngôn ngữ tự nhiên và vấn đề là bạn hiểu như thế nào bạn thấy đấy
Murph

4
Bravo .. Không đề cập đến thực tế là nó đọc một cách không tự nhiên, bạn có xu hướng chú ý đến nó nhiều hơn, do đó nắm bắt được những sai lầm tiềm ẩn.
mocj

7
@mocj - Vì vậy, tất cả chúng ta nên mã một cách rõ ràng nhất có thể để đảm bảo rằng mọi người đọc mã của chúng ta cần phải thực sự đọc mã của chúng tôi?
Kaz Dragon

6
@mocj - Tôi đánh giá cao điều đó, nhưng lập luận của bạn là "nói lắp não" khi bạn đọc điều kiện Yoda là một điều tốt. Tôi đang đặt câu hỏi rằng, nếu đó là trường hợp, chúng ta có nên đặt mục tiêu viết tất cả mã để chúng ta gây ra "những kẻ mắc kẹt não" không? Câu hỏi chính hãng.
Kaz Dragon

11

Tôi sẽ không gọi nó là có hại, nhưng nó đáng ghét. Vì vậy, không tôi sẽ không nói nó làm.


10

Tôi chưa bao giờ cảm thấy rằng toàn bộ 'nếu tôi quên a =?' bao giờ thực sự giữ trọng lượng nhiều. Vâng, bạn có thể mắc lỗi đánh máy, nhưng tất cả chúng ta đều mắc lỗi chính tả, có vẻ ngớ ngẩn khi thay đổi toàn bộ phong cách mã hóa của bạn vì bạn sợ mắc lỗi. Tại sao không biến tất cả các biến & hàm của bạn thành chữ thường mà không có dấu chấm câu, bởi vì bạn có thể quên viết hoa một cái gì đó hoặc quên một dấu gạch dưới một ngày?


5
Đó không phải là vấn đề của câu hỏi, vấn đề là "nó có hại không" - và không phải vậy. Một kích thích rất nhỏ ở tồi tệ nhất, nhưng không có hại.
Murph

1
Trong các ngôn ngữ động - hoàn toàn, bạn có thể gõ nhầm một biểu tượng và lãng phí thời gian của bạn sau đó để tìm nguồn gốc của lỗi
mojuba

3
với tất cả sự tôn trọng, khi bạn đã trải qua một đêm muộn (hoặc hai) và tìm nguồn (trong mã C ++) là a = thay vì ==, nó sẽ mang một trọng lượng nào đó.
DevSolo

2
@DevSolo: Tôi nghĩ điều đó thực sự nên xảy ra một hoặc hai lần trong sự nghiệp của bạn, nhưng không nhiều hơn thế
mojuba

9

Một số người sử dụng nó để làm cho nó rõ ràng chính xác những gì một điều kiện đang làm. Ví dụ:

Cách 1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

Cách 2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

Một số người cảm thấy rằng ví dụ thứ hai ngắn gọn hơn, hoặc các đối số đảo ngược minh họa điểm của một bài kiểm tra (có điều kiện) trước khi thử nghiệm.

Trong thực tế, tôi cũng không thực sự bận tâm. Tôi có thú cưng của tôi về phong cách và cái lớn nhất là sự không nhất quán. Vì vậy, hãy làm theo cách tương tự, nhất quán và tôi sẽ không đọc mã của bạn.

Trộn nó đến mức trông giống như sáu người khác nhau với phong cách đặc biệt của riêng họ làm việc cùng một lúc, tôi cảm thấy hơi khó chịu.


4
Ví dụ thứ hai khiến tôi đi "hả?" Đầu tiên là dễ đọc hơn nhiều. Ví dụ tuyệt vời. :)
Mateen Ulhaq

6

Đối với tôi, đó là điều hòa đơn giản. Là một người đã học (vào những năm 90) C và C ++, tôi đã quen với nó và vẫn sử dụng nó, mặc dù các lý do đã được giảm bớt.

Một khi bạn "có điều kiện" để nhìn vào phía bên trái cho "hằng số", nó trở thành bản chất thứ hai.

Tôi cũng chỉ sử dụng nó cho tương đương (hoặc tương đương phủ định), không phải cho lớn hơn / ít hơn.

Tôi hoàn toàn đồng ý với câu trả lời của @ Wonko.


5

Một trường hợp mà tôi thấy nó hữu ích là nơi phần biến của if khá dài và việc nhìn thấy các giá trị làm cho mã dễ đọc hơn. Các ngôn ngữ không gian tên rải rác có các ví dụ tốt nhất về điều này.

Ví dụ, một cái gì đó tôi đã làm việc với đăng nhập một lần có một tình huống mà bạn có thể có hai phiên đồng thời nếu một loại lỗi nhất định xảy ra và đã được phục hồi theo một cách nhất định vì vậy tôi phải thêm một trình xử lý cho bên trong nếu nó trông như thế đại loại như thế này:

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

Phải thừa nhận trong ví dụ này có những cách khác để làm điều này, nhưng đây sẽ là trường hợp phiên bản số đầu tiên có khả năng dễ đọc hơn.


2
Tôi nghĩ rằng từ khóa ở đây là "những cách khác để làm điều này";)
mojuba

trong trường hợp này là có, nhưng trong một số trường hợp đây vẫn là kết quả dễ đọc nhất. Quan điểm duy nhất của tôi là có một số lý do chính đáng để thực hiện việc này ngoài việc chống lại hành vi ngôn ngữ hoặc ide và loại o
Bill

Thành thật mà nói, tôi gặp khó khăn với các điều kiện của Yoda cho <= và> =. Dấu == là một vấn đề khác, bởi vì trong đầu tôi chỉ có thể chuyển đổi các ký hiệu xung quanh, nhưng trong trường hợp của bạn, tôi cần nhớ rằng số () phải lớn hơn hoặc bằng 2, và điều đó khá khó chịu khi xuất phát từ một dấu hiệu nhỏ hơn hoặc bằng nhau.
Alex

3

Nhưng các lỗi xảy ra. Và đôi khi bạn muốn một bài tập trong một toán tử vòng lặp trong đó bạn có thể kiểm tra sự bằng nhau, hoặc ít nhất đó là cách thực hành tiêu chuẩn để sử dụng nó.

Tôi giữ với nó phần nào. Lời khuyên mà tôi đã làm theo (có thể từ Code Complete) là giữ những gì nên là giá trị thấp hơn ở bên trái trong các so sánh. Tôi đã thảo luận điều này với một đồng nghiệp trước đó và anh ấy nghĩ nó thật điên rồ nhưng tôi đã quen với nó.

Vì vậy, tôi sẽ nói:

if ( 0 <= value )

Nhưng tôi cũng sẽ nói:

if ( value <= 100 )

Bình đẳng Tôi sẽ có xu hướng kiểm tra với biến ở bên trái, nó chỉ dễ đọc hơn.


1
Tôi đã quen với việc sử dụng if(y > x)tất cả các thời gian. Trừ khi ylà một hằng số.
Mateen Ulhaq

Tôi đã từng làm theo cách đó, nhưng một khi tôi có ý tưởng có các giá trị thấp nhất ở bên trái, tôi đã thấy mã của mình dễ đọc hơn rất nhiều trong nháy mắt.
glenatron
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.