2013-03-24 26 views
8

tôi đã sắp xếp một số mã cũ khi tôi stumbled khi một cấu trúc tương tự như sau:Thay NẾU với một biểu thức logic trong PHP

// function bar() returns a value 
// if the value is an instance of customException class, terminate with error code 
// else process the regular data 

$foo = bar(); 
checkForException($foo) && exit($foo->errorCode()); 
process($foo); 

Bây giờ lạ như nó có vẻ, đây là ngắn hơn rất nhiều sau đó

$foo=bar(); 
if(checkForException($foo)) { 
    exit($foo->errorCode(); 
} 
else { 
    process($foo); 
} 

Và phần nào dễ đọc hơn (ít nhất là sau sự ngạc nhiên ban đầu) sau đó

$foo=bar(); 
(checkForException($foo)) ? exit($foo->errorCode()) : process($foo); 

trong khi mã ngắn hơn không nhất thiết có nghĩa là mã dễ đọc hơn, tôi thấy điều này ở đâu đó ở giữa hai cách "chuẩn" ở trên.

Nói cách khác, thay vì

if($foo) { 
    bar(); 
} 
else { 
    // there is no real reason for this to exist, since 
    // I have nothing to write here, but I want to conform 
    // to the general coding practices and my coding OCD 
} 

Người ta có thể chỉ đơn giản là viết

$foo && bar(); 

Vì vậy, lý do đằng sau này sử dụng nhiều không nhìn thấy là những gì? Nó có thể đơn giản như là "Đừng sáng tạo lại bánh xe, viết dễ đọc hơn nếu/người khác, và nếu bạn thực sự muốn rút ngắn nó, đó là những gì nhà điều hành ternary là dành cho"?

EDIT: Hãy nhớ rằng mã trên đã nhanh chóng được lấy từ mã gốc và có nghĩa là chỉ là một ví dụ về việc sử dụng mã "ngắn mạch". Nếu bạn có thể, vui lòng hạn chế đề xuất cải tiến mã, vì đó không phải là kết quả mong muốn của câu hỏi.

Ví dụ số 2

userCheckedTheBox($user) && displayAppropriateInfo(); 
+1

Trong khuôn khổ có cấu trúc, bạn sẽ không sử dụng 'thoát' nhiều. Bên cạnh đó, một 'if/else' đầy đủ cho phép bạn sử dụng nhiều lệnh trong nhánh' else' - anyways đôi khi ngắn mạch rất hữu ích, chỉ cần không lạm dụng nó. – moonwave99

+0

Tại sao nó nên "lạ" (như trong "lạ như nó có vẻ") mà ít ký tự ngắn hơn nhiều ký tự? Bạn phải sống một cuộc sống được che chở. –

+0

"Vậy lý do đằng sau việc này không thấy nhiều việc sử dụng là gì?" --- bởi vì có nhiều loại lập trình viên khác nhau: một số viết mã "cool", khác - dễ hỗ trợ. – zerkms

Trả lời

3

Có một kỹ thuật cũ mà tôi cho là phổ biến trong các tập lệnh perl bị tấn công cùng nhau để hiển thị lỗi. pseudo-code:

myFunction() || exitWithError("Uh-oh") 

Khi mã hóa-đến-thời hạn và khi giao diện người dùng không cần phải xuất sắc, đó là cách nhanh chóng để tránh lỗi.

Phong cách cũng rất phổ biến trong javascript cho các thông số mặc định:

function myfunction(foo) { 
    foo = foo || 0; 
    // note that a non-zero default won't work so well, 
    // because the user could call the function with 0 
} 

và for null-kiểm tra:

var bar = foo && foo.property; 

Tôi thấy rằng một khi bạn đã quen với nó, nó rất dễ đọc và thường trực quan hơn if/else hoặc ?:. Nhưng bạn chỉ nên sử dụng nó khi nó có ý nghĩa. Sử dụng nó ở mọi nơi sẽ rất khó hiểu. Ví dụ: trong ví dụ của bạn, bạn nên không sử dụng. Cá nhân tôi sử dụng nó để kiểm tra lỗi đơn giản và một số giá trị mặc định là. Trong các dự án lớn, bạn hầu như luôn muốn làm nhiều hơn nữa khi một lỗi xảy ra, vì vậy trong những trường hợp đó bạn không nên sử dụng điều này.

Ngoài ra, bạn nên cẩn thận; điều này chỉ hoạt động ở các ngôn ngữ có đánh giá ngắn mạch (http://en.wikipedia.org/wiki/Short-circuit_evaluation). Và đôi khi andor ngắn mạch, trong khi &&|| thì không.

myfunction() or die("I'm melting!"); cũng khá hài lòng khi viết.

Cuối cùng, trống else khối dưới dạng quy tắc là điều tôi chưa bao giờ thấy trước đây hoặc nghe bất kỳ ai đề xuất. Có vẻ như rất vô nghĩa đối với tôi. Tùy chọn dễ đọc nhất cho ví dụ của bạn, khá đơn giản:

if($foo) { 
    bar(); 
} 
6

Trong khi $foo && bar(); là ít dòng mã đó là ít hơn nhiều có thể đọc được. Làm cho mã của bạn dễ hiểu thường quan trọng hơn là giảm tổng số LoC. Ngay cả khi bạn không làm việc trong môi trường với nhiều lập trình viên, bạn sẽ phải quay lại và đọc mã của bạn tại một thời điểm nào đó trong tương lai, và có thể bạn sẽ không thể nhớ lý do đằng sau mỗi dòng mã số (Eagleson's Law).

Nói chung, bạn nên hạn chế việc sử dụng các loại câu lệnh này chỉ với những trường hợp mà ý định của lập trình viên là hoàn toàn rõ ràng. Theo tôi, thực hành rất xấu là có mã kiểm tra điều kiện và mã mà chủ động sửa đổi trạng thái hiện tại của chương trình trên cùng một câu lệnh.

Dưới đây là một sử dụng chấp nhận được cho các loại mã:

$isValidUser = $userName && usernameIsValid(); 

Ở đây, cả hai bên của các nhà điều hành && đang thử nghiệm một điều kiện, thực tế là phía bên phải đang kêu gọi một chức năng để làm điều đó không gây hại khả năng đọc mã.

1

Đối với các lỗi bạn nên sử dụng ngoại lệ thật:

try { 
    $foo = bar(); 
} catch(FooException $e) { 
    exit($e->errorCode); 
} 
process($foo); 

Xem the documentation for errorhandling.

+1

OP _is_ sử dụng các ngoại lệ thực ('customException'), chúng không bị ném, nhưng được sử dụng như một sự trả về giá trị ... –

1

Mã nào đang hoạt động, trả lại phiên bản CustomException chỉ không thêm.Tại sao không thay đổi định nghĩa chức năng một chút:

function bar() 
{ 
    $stuff = true; 
    if ($stuff === true) 
    { 
     return 'Value on success'; 
    } 
    //something went wrong: 
    throw new CustomException('You messed up'); 
} 
try 
{//here's the outlandish try-catch block 
    $foo = bar(); 
} 
catch (CustomException $e) 
{ 
    exit($e->message());//fugly exit call, work on this, too 
} 
//carry on here, no exception was thrown 

Ngoài ra, gọi hàm thứ hai (checkForException($foo)) chỉ là vô lý. Các cuộc gọi chức năng có giá rẻ, nhưng không miễn phí. Bạn muốn biết nếu hàm trả về một thể hiện của CustomException? Đừng biến nó thành một hàm, nhưng sử dụng instanceof. Sử dụng ngắn mạch để giữ số lượng ký tự (quảng cáo do đó phân tích-thời gian) xuống, trong khi đồng thời lãng phí tài nguyên trên tất cả các cấp khác là ngớ ngẩn như quay lên trong một chiếc Mustang V8 trên một khóa học siêu miling.

+0

Tôi đã chỉnh sửa câu hỏi của mình để phản ánh tốt hơn kết quả mong muốn của nó. Trường hợp ngoại lệ đang được ném và xử lý, các tên chỉ là một chút đáng tiếc. – user1853181

+0

@ user1853181: Xin lỗi vì đã tiếp tục đập như thế này, nhưng rõ ràng bạn không ném ngoại lệ. Nếu bạn đã có, đánh giá ngắn mạch sẽ thất bại, và tất cả những gì bạn thấy là một thông báo nói rằng 'Lỗi: uncaught Exception' –

+0

Theo như tôi đã hiểu, trình xử lý ngoại lệ trong thanh() đang ghi lại thông tin ngoại lệ và trả về đối tượng tùy chỉnh (có mã lỗi trong số các thông tin khác) cho người gọi. Tôi chắc chắn có một ý định tốt đằng sau đó, cố gắng tìm ra nó ngay bây giờ ... Nhưng đây thực sự là chủ đề cho một câu hỏi khác, nếu cần. – user1853181

0

Một giải pháp có thể cho vấn đề của bạn:

$foo = bar(); 
!checkForException($foo) or exit($foo->errorCode); 
process($foo); 

Nhưng tốt hơn sự thay đổi !checkForException cho isNoException hoặc một cái gì đó dọc theo những đường.

Các vấn đề liên quan