2011-01-30 47 views
14

Tôi biết, có otherquestions về tuyên bố goto được giới thiệu trong PHP 5.3.Trường hợp sử dụng hợp lệ của goto trong PHP là gì?

Nhưng tôi không thể tìm thấy bất kỳ câu trả lời nào trong số đó là "last resort", "xkcd", "evil", "bad", "EVIL !!!". Nhưng không có ví dụ hợp lệ. Chỉ những câu lệnh không có bất kỳ cách sử dụng nào. Hoặc báo cáo rằng có một số trường hợp sử dụng hiếm (một lần nữa, không có ví dụ).

Vì vậy, câu hỏi là: "Trường hợp sử dụng hợp lệ của goto bằng PHP là gì?". Câu trả lời cho "Is goto tà ác?" không được chào đón và sẽ được giảm giá. Cảm ơn :)

Hoặc ai đó có liên kết đến RFC nơi quyết định được giải thích - Tôi không thể tìm thấy.

+0

'goto' thuận tiện như cá trích đỏ trong các cuộc thảo luận về tính hữu ích hoặc ác ý của cấu trúc ngôn ngữ, bất kể việc sử dụng thực tế nào. – mario

+1

@mario: Tôi đã cố gắng giải thích rõ ràng trong câu hỏi của mình, rằng tôi không muốn biết liệu đó có phải là điều xấu hay không. Những câu hỏi như vậy là một sự lãng phí thời gian. Tôi quan tâm đến các ví dụ cụ thể. Và do đó tôi coi đây không phải là một câu hỏi "chủ quan hoặc tranh luận". – NikiC

+0

@NikiC, Btw khi bạn nói rằng bạn là ["nhà phát triển lõi PHP"] (http://stackoverflow.com/users/385378/nikic), điều đó có nghĩa là bạn biết C? – Pacerier

Trả lời

6

Một cách sử dụng có thể (tuy nhiên có thể được thực hiện bằng các phương tiện khác) đang triển khai finite state machine.

+1

Máy tính trạng thái hữu hạn có giống như một trình phân tích cú pháp không? – NikiC

+1

http://en.wikipedia.org/wiki/Finite-state_machine – Mchl

+0

Hm, điều đó không giúp được gì nhiều cho tôi. Bạn có thể đưa ra một ví dụ về một máy trạng thái hữu hạn hoặc nơi nó được sử dụng? Bài viết Wiki khá lý thuyết, tôi không thể tìm thấy một ứng dụng trong đó. – NikiC

2

goto toán tử có thể được sử dụng để phá vỡ vòng lặp nhiều cấp.

này đặc biệt goto ứng dụng ví dụ được đưa ra at goto manual page:

Bạn cũng không thể nhảy vào bất kỳ loại vòng lặp hoặc cấu trúc switch. Bạn có thể nhảy ra khỏi những điều này, và sử dụng phổ biến là sử dụng một goto thay cho một break đa cấp.

+3

Chúng ta không có 'phá vỡ x;' cho điều đó? 'break 4;' sẽ phá vỡ bốn vòng lặp. [Hướng dẫn sử dụng cho 'ngắt'] (http://php.net/break) – NikiC

+0

Có, chúng tôi có.BTW, nếu được sử dụng đúng cách, 'goto' có thể dẫn đến mã nhỏ hơn' break x'. Có lẽ đây là một nỗ lực để cung cấp cơ chế phá vỡ tương tự như phá vỡ nhãn/tiếp tục trong Java. – Kel

+3

Tôi sẽ đánh giá cao một ví dụ trong đó 'goto' sạch hơn khi' ngắt x'. Tôi không thể tưởng tượng một mình. – NikiC

2

Goto đã được thay thế lớn bằng các câu lệnh chuyên ngành như continue, break, try...catch. Trong những năm tôi làm việc với PHP, tôi không cảm thấy nó có thể giúp tôi một lần. Trong các ngôn ngữ như C++ không có tuyên bố break x, nó có thể được sử dụng để nhảy ra khỏi vòng lặp lồng nhau, nhưng kể từ khi PHP có nó, không có lý do gì.

Code Complete có chương rất đẹp và chi tiết về gotos. Trích dẫn hai đoạn cuối cùng:

Sử dụng gotos là vấn đề tôn giáo. Giáo điều của tôi là trong các ngôn ngữ hiện đại, bạn có thể dễ dàng thay thế chín trong mười gotos bằng các cấu trúc tuần tự tương đương. Trong những trường hợp đơn giản này, bạn nên thay thế gotos ra khỏi thói quen. Trong trường hợp khó khăn, bạn vẫn có thể loại bỏ goto trong chín trong mười trường hợp: Bạn có thể ngắt mã thành các thường trình nhỏ hơn, sử dụng thử cuối cùng, sử dụng ifs lồng nhau, kiểm tra và thử lại biến trạng thái hoặc cấu trúc lại một điều kiện. Loại bỏ các goto là khó khăn hơn trong những trường hợp này, nhưng đó là tập thể dục tinh thần tốt và các kỹ thuật thảo luận trong phần này cung cấp cho bạn những công cụ để làm điều đó.

Trong trường hợp còn lại trong số 100 trường hợp, goto là giải pháp hợp pháp cho vấn đề, hãy ghi rõ và sử dụng nó. Nếu bạn có giầy mưa, bạn không nên đi bộ quanh khối để tránh vũng bùn. Nhưng hãy giữ cho tâm trí của bạn cởi mở với các phương pháp tiếp cận goto-ít được đề xuất bởi các lập trình viên khác. Họ có thể thấy một cái gì đó bạn không.

Tôi thấy rất khó hiểu tại sao nhóm PHP lại bận tâm thêm nó (sau tất cả những năm chúng tôi sống trong hòa bình mà không có nó).

+4

Trong PHP tuy nhiên 'goto' được thêm vào khi tất cả các câu lệnh bạn đề cập đã có sẵn từ lâu. Do đó câu hỏi tôi đoán. – Mchl

+0

@Mchl, Chính xác. Câu hỏi đặt ra là tại sao 'goto' được thêm vào. – Pacerier

5

Xem PHP Architect - GOTO in PHP 5.3: is it Really That Evil?

Bài viết này đưa ra một tổng quan ngắn về việc tại sao GOTO có thể hữu ích, tại sao chúng ta có nó trong PHP (từ năm 2004) và tại sao nó là/là gây tranh cãi. Câu trả lời chung dường như là: GOTO hầu như vô dụng và nên tránh trừ khi trong các không gian ứng dụng rất hẹp (như xây dựng một trình biên dịch):

Một điều chắc chắn: có một số ứng dụng trong đó nhà phát triển giỏi có thể đặt GOTO sử dụng tốt để sản xuất mã đơn giản và hiệu quả hơn, nhưng chúng có lẽ không phải là loại chương trình chính thống mà nhà phát triển trung bình của bạn sẽ viết; do đó, có một mối quan tâm hợp pháp ở đây rằng các lập trình viên thiếu kinh nghiệm sẽ sử dụng GOTO để gây thiệt hại chung cho mã của họ.

Xem thêm một số bản gốc thảo luận newslist/cãi đề cập trong bài viết:

Cũng xem thảo luận thuyết bất khả tri ngôn ngữ kỹ lưỡng này về GOTO considered harmful at C2 Wiki

+1

Được rồi, do đó, một lần nữa tự động hóa nhà nước hữu hạn, lexing, phân tích cú pháp, biên dịch. Đó dường như là trường hợp sử dụng số một (hoặc thậm chí là duy nhất). – NikiC

+0

@nikic yes. chắc chắn rồi. – Gordon

3

Một trường hợp tôi sử dụng nó là khi tôi có kiểm tra đa cấp để thực hiện và không muốn thêm mã phụ khi tôi chỉ có thể chuyển đến phần có liên quan sau khi kiểm tra của tôi. Ví dụ, có hệ thống này kiểm tra trạng thái của các máy khác nhau trong một nhà kho, và không thành công nhà kho và gửi một cảnh báo nếu bất kỳ một phần của bất kỳ một hệ thống nào bị chết, trong mã giả nó đi như thế này:

if(hsensor[status] != OK) { 
    alert = Humidity sensor hsensor[fail_id] failed with error hsensor[fail_error] 
    goto sendAlert; 
} 

if(cosensor[status] != OK) { 
    alert = Co2 sensor cosensor[fail_id] failed with error cosensor[fail_error] 
    goto sendAlert; 
} 

bằng cách đó, nếu bất cứ điều gì thất bại, tôi có thể bỏ qua tất cả kiểm tra khác và đi thẳng qua để cảnh báo. Bất kỳ ai đang gọi sẽ nhận được cảnh báo và kéo lên kết quả đầy đủ của bất kỳ chức năng nào được gọi là cảnh báo để họ có thể sửa chữa nó.

+2

Đây là trường hợp sử dụng tốt nhất mà tôi biết. Phương án thay thế là một loạt các câu lệnh lồng nhau hoặc một biến trạng thái toàn cục mà bạn kiểm tra trong mỗi câu lệnh if. Theo tôi, goto là cách sạch nhất để thực hiện điều này. –

+1

Dude này phải là câu trả lời được chấp nhận. – Pacerier

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