Làm thế nào tôi có thể định dạng lại tình trạng của mình để làm cho nó tốt hơn?


35

Tôi có một điều kiện

if(exists && !isDirectory || !exists)
{}

Làm thế nào tôi có thể sửa đổi nó, để nó có thể dễ hiểu hơn.


1
isDirectory có giá trị gì khi tồn tại là sai?
marktani

1
tồn tại là loại Bool, isDirectory cũng là biến loại BOOL
Spynet

5
if (! isDirectory) ... (tồn tại | |! tồn tại) sẽ luôn đúng.
Cá mập

@Shark - Điều gì xảy ra nếu existsisDirectorycả hai đều đúng?
pasawaya

Tôi đọc tiêu đề là "Tôi có một vấn đề về tính cách, tôi có thể xóa tâm trí của mình để khắc phục nó không". Vâng, tôi mệt mỏi.
Annan

Câu trả lời:


110

|| là giao hoán

if(!exists || (exists && !isDirectory))

là tương đương

Bây giờ bởi vì tồn tại luôn luôn đúng trong phần thứ hai của ||bạn, bạn có thể bỏ &&:

if(!exists || !isDirectory)

Hoặc bạn có thể tiến thêm một bước và làm:

if(!(exists && isDirectory))

5
Điều được ngụ ý nhưng không được đề cập rõ ràng ở đây là &&có độ ưu tiên cao hơn (ít nhất là trong hầu hết các ngôn ngữ được biết đến - có thể có ngoại lệ) hơn ||. Như vậy a && b || clà tương đương (a && b) || cnhưng không a && (b || c).
Péter Török

27
Tôi nghĩ, đó !exists || !isDirectorylà "dễ hiểu" hơn, bởi vì, isDirectorykhông thể đúng nếu !exists. Vì vậy, là một con người, chúng ta sẽ nói "nếu nó không tồn tại hoặc nó [tồn tại và nó] không phải là một thư mục".
Duros

6
Tôi thích! Tồn tại | | ! isDirectory trên cái cuối cùng.
Apoorv Khurasia

3
||chỉ giao hoán nếu được sử dụng trên các giá trị không có tác dụng phụ - ví dụ: nếu được sử dụng với các chức năng, một số chức năng có thể không được gọi (ngắn mạch) hoặc trả về một giá trị khác theo thứ tự khác.
orlp

26
Bất cứ ai dựa vào mức độ ưu tiên tương đối của '&&', '||', '==', '! =', V.v. và không làm rõ ý định của họ bằng cách sử dụng dấu ngoặc xứng đáng bị bắn. Trong tất cả các ngôn ngữ, một cái gì đó như 'a && b || c 'tương đương với một bình luận nói rằng tác giả có thể làm hỏng toàn bộ sự việc trong sự vội vàng của họ để tránh gõ thêm một vài ký tự.
Brendan

51

Theo quy trình, tôi đề nghị xây dựng một bảng chân lý:

e = exists
d = isDirectory

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0

Điều này phù hợp với NANDhoạt động , đơn giản là:

!(exists && isDirectory)

Nếu bạn không nhớ tất cả các cổng logic của mình, wikipedia có một tài liệu tham khảo thú vị với các bảng chân lý để khởi động .


@Christoffer Hammarström đưa ra một điểm quan trọng về tình trạng isDirectorybị ràng buộc với trạng thái exists. Giả sử rằng chúng tham chiếu đến cùng một tham chiếu và rằng không thể có trạng thái nơi tham chiếu không tồn tại là một thư mục, bảng chân lý có thể được viết như sau:

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0

Cái n/anày được sử dụng để đại diện cho một trạng thái không quan trọng. Việc giảm chấp nhận được có thể dẫn đến một trong hai 1hoặc 0cho các trạng thái dẫn đến n/a.

Với suy nghĩ này, !(exists && isDirectory)vẫn là một giảm hợp lệ, dẫn đến một 1cho !e && d.

Tuy nhiên, !isDirectorysẽ là một giảm đơn giản hơn nhiều, kết quả là 0cho !e && d.


4
Bước tiếp theo là nhận ra rằng isDirectoryphụ thuộc vào exists. Nó không thể là một thư mục và không tồn tại.
Christoffer Hammarström

@Christoffer Hammarstrom, Ngoài ngữ cảnh Tôi không thể cho rằng các biến đề cập đến cùng một điều, nhưng đó là một điểm hợp lệ. Cột kết quả phải được điền n/avào những nơi không thể đạt được trạng thái và phương trình giảm tương ứng.
zzzzBov

Chà, nếu các biến đề cập đến hai bối cảnh khác nhau, thì chúng quá ngắn gọn và cần được đổi tên.
Christoffer Hammarström

Nhưng xây dựng một bảng chân lý và đánh giá nó là NP-đầy đủ!
Thomas Eding

@ThomasEding, tôi có hai câu trích dẫn cho bạn, "Về lý thuyết, lý thuyết và thực hành là như nhau; trong thực tế, chúng không như vậy." và "Tối ưu hóa sớm là gốc rễ của mọi tội lỗi."
zzzzBov

22

Để dễ đọc hơn, tôi muốn trích xuất các điều kiện boolean cho các phương thức:

if(fileNameUnused())
{...}

public boolean fileNameUnused() {
   return exists && !isDirectory || !exists;
}

Hoặc với một tên phương pháp tốt hơn. Nếu bạn có thể đặt tên cho phương thức này một cách chính xác, người đọc mã của bạn sẽ không hiểu được điều kiện boolean có nghĩa là gì.


+1 để nói điều gì đó về tên hữu ích. Nhưng ở đâu đó bạn sẽ phải định dạng lại điều kiện.
Apoorv Khurasia

4
Một cách khác ít cực đoan hơn, vẫn truyền đạt ý định, chỉ là đặt tên cho điều kiện được sử dụng:boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Steven

8

Bạn chỉ có thể cố gắng đóng đinh trường hợp không đi và bảo lãnh nếu điều đó xuất hiện.

while(someCondition) {

    if(exists && isDirectory)
        continue;
        // maybe "break", depends on what you're after.

        // the rest of the code
}

hoặc thậm chí

function processFile(someFile)
{ 
    // ...
    if(exists && isDirectory)
       return false;
    // the rest of the code
    // ...
}

Không phá vỡ, tiếp tục và tuyên bố trả lại nhiều hơn một được coi là mã có mùi?
Freiheit

8
@Freiheit Nó phụ thuộc vào bối cảnh. Đôi khi một tuyên bố hoàn trả sớm được sử dụng để giảm thụt đầu dòng, do đó tăng cường khả năng đọc.
marco-fiset

Câu trả lời tốt nhất - điều kiện phức tạp lãng phí lượng lớn thời gian đọc và hiểu chính xác chúng. Kết quả là thường được "lấy như đọc" dẫn đến các lỗi sâu sắc.
mattnz

6

Bạn có thể sử dụng một bảng chân lý như được chỉ ra. Bước thứ hai có thể là bản đồ KV để giảm thiểu số lượng điều khoản.

Sử dụng định luật đại số Boolean là một cách tiếp cận khác:

A = tồn tại
B =! IsDirectory
! A =! Tồn tại

&& = *
|| = +

[Chỉnh sửa]
Một biến đổi đơn giản hơn, bởi vì các hoạt động AND và OR là phân phối lẫn nhau:

tồn tại &&! isDirectory || ! tồn tại
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Chỉnh sửa]

tồn tại &&! isDirectory || ! tồn tại
= A * B +! A
= A * B +! A * 1 // Danh tính
= A * B +! A * (B + 1) // Annihilator
= A * B +! A * B +! A / / Phân phối và Danh tính
= B * (A +! A) +! A // Phân phối
= B * 1 +! A // Bổ sung 2
= B +! A // Danh tính
=! IsDirectory || ! tồn tại

Hoặc với bổ sung kép (!! x = x):

A * B +! A
= !! (A * B +! A)
=! (! (A * B) * A)
=! ((! A +! B) * A)
=! (! A * A + ! B * A)
=! (0 +! B * A)
=! (! B * A)
= B +! A
=! IsDirectory || ! tồn tại


+1 cho việc sử dụng các quy tắc chính thức (mặc dù tôi chưa bao giờ thấy một trong những quy tắc này sau năm đầu tiên ở trường đại học).
Nemanja Boric


5

Tôi không thích sử dụng "!" khi có nhiều hơn một điều kiện trong biểu thức. Tôi sẽ thêm các dòng mã để dễ đọc hơn.

doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist) 
   {}

+1 Điều này giúp đọc dễ dàng hơn dưới dạng "nếu là tệp hoặc không tồn tại" gần với tiếng Anh hơn.
Phil

Đây là một cấu trúc lại được gọi là Giới thiệu Giải thích Biến .
Eddie Gasparian

1

Như đã chỉ ra trước đó, tình trạng có thể được giảm xuống:

if (!(exists && isDirectory))

Tuy nhiên, tôi sẽ đặt cược rằng một thư mục ngụ ý sự tồn tại. Nếu vậy, chúng ta có thể giảm điều kiện xuống:

if (!isDirectory)
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.