Có bao giờ OK cho một điều kiện có tác dụng phụ? [đóng cửa]


10

Tôi đang tham gia khóa học cấu trúc dữ liệu trung gian như một điều kiện tiên quyết để tham gia chương trình MS MS tại một trường đại học mà mọi người ở Mỹ đều nghe thấy. Một dòng mã được viết trong lớp khiến tôi chú ý:

if (a > 33 | b++ < 54) {...}

Điều này sẽ không vượt qua một đánh giá mã tại nơi làm việc của tôi. Nếu bạn đã viết mã như thế này trong một cuộc phỏng vấn, đây sẽ là một cuộc đình công đáng kể chống lại bạn. (Ngoài việc là một điều kiện có tác dụng phụ, nó còn thông minh với chi phí rõ ràng.)

Trên thực tế, tôi chưa bao giờ thấy một điều kiện có tác dụng phụ và Googling cũng không bật lên nhiều. Một sinh viên khác ở lại sau giờ học để hỏi về nó, vì vậy tôi không phải là người duy nhất nghĩ rằng điều này là kỳ lạ. Nhưng giáo sư khá kiên quyết rằng đây là mã có thể chấp nhận được và ông sẽ viết một cái gì đó giống như vậy tại nơi làm việc. (Công việc FT của anh ấy là SWE hiệu trưởng tại một công ty mà bạn đã nghe nói tới.)

Tôi không thể tưởng tượng một thế giới trong đó dòng mã này sẽ được chấp nhận, chứ đừng nói là mong muốn. Tôi có lầm không? Được không Còn trường hợp tổng quát hơn: điều kiện có tác dụng phụ thì sao? Những cái đó có ổn không?


7
Dòng đó nên được thu thập từ quỹ đạo. Hai lần cho biện pháp tốt.
Blrfl

8
Một nit: Một ống đơn (thanh dọc) là một bit - hoặc trong hầu hết các ngôn ngữ, thay vì "hoặc" logic. Nó không bị đoản mạch nếu phía bên tay trái là đúng. Vì điều kiện này có tác dụng phụ ở phía bên phải, nó tạo ra sự khác biệt đặc biệt lớn trong kết quả.
Jonathan Eunice

2
Có những thành ngữ được sử dụng trong các ngôn ngữ khác nhau sẽ thuộc loại này, nhưng vì chúng "nổi tiếng" hoặc "bình thường" không gây ra vấn đề. Dòng trong câu hỏi dường như không thuộc danh mục sử dụng thành ngữ nên tôi tránh nó.
Jaydee

2
@JonathanEunice, vâng, một số người đã nhầm lẫn về đánh giá ngắn mạch. Không phải là một lỗi đánh máy trên phần của tôi.
rianjs

5
Nhìn vào mặt tươi sáng. Bây giờ bạn biết thêm một công ty nơi bạn KHÔNG muốn phỏng vấn.
John R. Strohm

Câu trả lời:


23

một tác dụng phụ bán có điều kiện tôi có thể nghĩ là ổn:while(iter.MoveNext())

Điều đó nói rằng, tôi nghĩ rằng điều này chủ yếu rơi vào thể loại " không bao giờ là một vòng loại thực sự lớn". Tôi có thể nghĩ về một vài trường hợp hiếm hoi mà tôi thấy nó có thể chấp nhận được, nhưng nói chung điều này là tệ hại và cần tránh.

Tôi cũng không thể nghĩ ra một kịch bản mà dòng cụ thể đó có thể được chấp nhận, nhưng tôi cũng không thể nghĩ ra một kịch bản mà dòng cụ thể đó sẽ hữu ích , vì vậy thật khó để tưởng tượng bối cảnh của nó.


Nó chỉ là một dòng vứt đi trong một phương pháp trong lớp. Nó không có ý định làm bất cứ điều gì hữu ích.
rianjs

4
Tương tự, while(v = *p++)kiểu quét C / C ++ thông qua một mảng kết thúc bằng không (ví dụ chuỗi C) là khá phổ biến và được chấp nhận rộng rãi.
Phil Miller

3
Tôi thường coi các điều kiện vòng lặp của biểu mẫu while(c = input.read() != '\n')là thành ngữ hợp lý.

1
Có thể có một vài thành ngữ phổ biến được chấp nhận, nhưng rõ ràng "thông minh với chi phí rõ ràng" rơi vào trại KHÔNG BAO GIỜ.
Julia Hayward

Tôi hoàn toàn quên mất iter.MoveNext (). Một trường hợp hoàn toàn hợp lý cho một điều kiện có tác dụng phụ. Cảm ơn!
rianjs

8

Trong thế giới của tôi, việc đọc từ bộ nhớ có thể được coi là tác dụng phụ (ví dụ: bộ nhớ được ánh xạ IO).

Bây giờ, hãy xem xét những điều sau đây:

    while( ( *memory_mapped_device_status_register & READY_FLAG) == 0) {
       // Wait
    }

Và so sánh với:

    status = *memory_mapped_device_status_register;
    while( ( status & READY_FLAG) == 0) {
        // Wait
        status = *memory_mapped_device_status_register;
    }

Đã tránh các tác dụng phụ (đọc) trong điều kiện giúp dễ đọc; hoặc nó chỉ trùng lặp mã và thêm lộn xộn?

Điều kiện không có tác dụng phụ là không ổn (nếu điều đó làm cho mã ít đọc hơn) và điều kiện cũng không có tác dụng phụ (nếu điều đó làm cho mã dễ đọc hơn). Yếu tố chính là "khả năng đọc". Mọi thứ khác là các quy tắc được tạo ra bởi những kẻ ngốc trong một nỗ lực sai lầm để cải thiện khả năng đọc (trong khi thường có tác dụng ngược lại).


3

Như mọi khi với những câu hỏi như vậy, đây là vấn đề bằng cấp. Nếu có bằng chứng rõ ràng rằng bất kỳ tác dụng phụ nào trong một ifbiểu thức luôn dẫn đến mã kém hơn, thì việc tạo ra các biểu thức đó là không hợp pháp. Nhà thiết kế ngôn ngữ có thể ideosyncratic, con người có thể sai lầm, nhưng họ không phải ngu ngốc.

Điều đó nói rằng, các ví dụ về tác dụng phụ hợp lý trong một là ifgì? Ví dụ: giả sử bạn được yêu cầu về mặt pháp lý để ghi lại tất cả và mọi quyền truy cập vào tài sản Pcủa một thực thể Echo mục đích kiểm toán. (Hãy tưởng tượng bạn đang làm việc trong một nhà máy làm giàu uranium và có các biện pháp kiểm soát pháp lý rất nghiêm ngặt về những gì mã của bạn được phép làm và cách nó được thực hiện.) Sau đó, bất kỳ ifkiểm tra nào thuộc tính đó sẽ gây ra tác dụng phụ của nhật ký kiểm toán được gia hạn.

Đó là một mối quan tâm xuyên suốt khá rõ ràng, nó không ảnh hưởng đến lý do của bạn về trạng thái chương trình (rất nhiều) và bạn có thể thực hiện nó để nó hoàn toàn vô hình và không gây xao lãng khi bạn xem lại dòng với if(ẩn đi trong accessor, hoặc thậm chí tốt hơn thông qua AOP). Tôi muốn nói rằng đó là một trường hợp khá rõ ràng về tác dụng phụ không phải là vấn đề đáng lo ngại. Các tình huống tương tự có thể được tưởng tượng khi bạn chỉ muốn đếm các lần thực hiện chi nhánh cho mục đích định hình, v.v.

Càng nhiều tình huống giảm nhẹ này biến mất, công trình càng trở nên xa lạ. Nếu một loại vòng lặp cụ thể (ví dụ như if((c = getc()) == 'x') { quit(); }được cộng đồng ngôn ngữ biết đến và chấp nhận, thì nó sẽ ít gặp vấn đề hơn so với khi bạn phát minh ra nó một cách tự nhiên, v.v. những thứ khủng khiếp hơn mà tôi thậm chí sẽ không gõ, chúng thật kinh khủng.


2

Mặc dù mã thực sự có mùi, nhưng nó có ưu điểm là đơn giản hơn (và có thể nhanh hơn nếu bạn không có trình biên dịch tối ưu hóa tốt) so với tương đương if (a > 33 | b < 54) {b++; ...} else b++;

nhưng tất nhiên có thể tối ưu hóa nó thành như sau (nhưng xem ra! cái này có hành vi khác trong trường hợp tràn!): b++; if (a > 33 | b < 53) {...}

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.