2008-08-21 69 views
5

Tôi đã nghe tin đồn rằng PHP đang có kế hoạch giới thiệu một lệnh "goto". Nó phải làm gì?Lệnh GOTO trong PHP?

Tôi đã thử tìm kiếm một chút, nhưng không tìm thấy bất kỳ điều gì mô tả khủng khiếp. Tôi hiểu rằng đó không phải là lệnh "GOTO 10" giống như ...

+1

Và trên thực tế nó là trong PHP5. Và những gì nó làm là, "chỉ đơn giản goto". –

Trả lời

9

Họ không thêm GOTO thực, nhưng mở rộng từ khóa BREAK để sử dụng nhãn tĩnh. Về cơ bản, nó sẽ được tăng cường khả năng thoát ra khỏi chuyển đổi lồng nhau nếu báo cáo. Dưới đây là ví dụ khái niệm tôi thấy:

<?php 
for ($i = 0; $i < 9; $i++) { 
    if (true) { 
     break blah; 
    } 
    echo "not shown"; 
    blah: 
    echo "iteration $i\n"; 
} 
?> 

Tất nhiên, một khi GOTO "tin đồn" đi ra ngoài, không có gì để ngăn chặn một số kẻ ác để tuyên truyền thêm COMEFROM trò đùa. Hãy để ngón chân của bạn.

Xem thêm:

http://www.php.net/~derick/meeting-notes.html#adding-goto

+4

Tôi nghĩ rằng đó là thực sự khó hiểu, bởi vì một break trên riêng của mình sẽ nhảy ra khỏi vòng lặp, không chỉ là tuyên bố nếu. – DisgruntledGoat

3

Cấp, tôi không phải là lập trình viên PHP và tôi không biết triển khai chính xác GOTO của PHP sẽ như thế nào, nhưng đây là sự hiểu biết của tôi về GOTO:

GOTO chỉ là một tuyên bố kiểm soát luồng rõ ràng hơn như bất kỳ tuyên bố nào khác. Giả sử bạn có một số vòng lặp lồng nhau và bạn chỉ cần tìm một thứ. Bạn có thể đặt trong một câu lệnh có điều kiện (hoặc một số) và khi các điều kiện được đáp ứng đúng, bạn có thể sử dụng câu lệnh GOTO để thoát khỏi tất cả các vòng lặp (thay vì có câu lệnh 'break' ở mỗi cấp làm việc với câu lệnh điều kiện . cho mỗi và vâng, tôi tin rằng việc thực hiện truyền thống là phải có nhãn tên rằng tuyên bố GOTO có thể nhảy đến theo tên Bạn có thể làm một cái gì đó như thế này:.

for(...) { 
    for (...) { 
     for (...) { 
     // some code 
     if (x) GOTO outside; 
     } 
    } 
} 
:outside 

Đây là một đơn giản hơn (và hiệu quả hơn) thực hiện mà không có báo cáo GOTO. Tương đương sẽ là:

for(...) { 
    for (...) { 
     for (...) { 
      // some code 
      if (x) break; 
     } 
     if(x) break; 
    } 
    if(x) break; 
} 

Trong trường hợp thứ hai (thông thường là thực tế) có thre e báo cáo có điều kiện, mà rõ ràng là chậm hơn so với chỉ có một. Vì vậy, vì lý do tối ưu hóa/đơn giản hóa, bạn có thể muốn sử dụng các câu lệnh GOTO trong các vòng lặp lồng nhau chặt chẽ.

+0

Bạn không cần GOTO vì lý do này. Xem câu trả lời của tôi cho một cách có cấu trúc hơn để thể hiện vi phạm các vòng lặp mà luôn luôn hoạt động và giới thiệu không kém hiệu quả. Goto cho mục đích này chỉ là câm. (Không phải là một sự phản ánh trên bạn.) –

0

looks như hiện đang ở bản 5.3 PHP, nhưng chưa được ghi đầy đủ. Từ những gì tôi có thể nói nó chia sẻ cú pháp goto của nó với C, do đó, nó phải được dễ dàng để nhận và sử dụng. Chỉ cần nhớ Dijkstra's warning và chỉ sử dụng nó khi cần thiết.

0

@ steveth45

Quy tắc của ngón tay cái là nếu bạn đã lồng mã hơn 3 cấp độ sâu, bạn đang làm gì đó sai.

Sau đó, bạn không cần phải lo lắng về việc sử dụng nhiều câu lệnh phá vỡ hoặc goto: D

+0

Tôi hơi đồng ý nhưng đôi khi nhiều cấp độ của vòng lồng nhau trong không thể tránh khỏi và không nên bị chế giễu. – Christian

0

Trong ví dụ do steveth45 bạn có thể sử dụng một chức năng thay vì:

function findItem(...) { 
    for (...) { 
    for (...) { 
     for (...) { 
     if (x) { 
      return theItem; 
     } 
     } 
    } 
    } 
} 

// no need for label now 
theItem = findItem(a, b, c); 
5

Tôi luôn ngạc nhiên về việc các nhà thiết kế PHP câm lặng đến mức nào. Nếu mục đích của việc sử dụng gotos là làm phá vỡ ra khỏi nhân lồng nhau vòng có một cách tốt hơn hiệu quả hơn: khối mã nhãn và phá vỡ tuyên bố rằng có thể tham khảo nhãn:

a: for (...) { 
    b: for (...) { 
     c: for (...) { 
       ... 
       break a; 
      } 
     } 
    } 

Bây giờ là rõ ràng mà loop/khối để thoát ra, và lối ra được cấu trúc; bạn không thể nhận được mã spaghetti với điều này giống như bạn có thể với gotos thực.

Đây là một ý tưởng cũ kỹ, cũ kỹ. Thiết kế quản lý dòng chảy kiểm soát tốt cấu trúc đã được giải quyết từ những năm 70, và các tài liệu trên tất cả các điều này là dài kể từ khi viết lên. Định lý Bohm-Jacopini cho thấy rằng bạn có thể mã bất cứ điều gì với chức năng gọi, nếu-sau đó-người khác, và trong khi vòng lặp. Trong thực tế, để thoát ra khỏi các khối lồng nhau sâu, Bohm-Jacopini phong cách mã hóa yêu cầu thêm cờ boolean ("đặt cờ này để thoát khỏi vòng lặp") được mã hóa vụng về khôn ngoan và không hiệu quả (bạn không muốn như vậy cờ trong vòng lặp bên trong của bạn). Với if-then-else, các vòng lặp khác nhau (trong khi, cho) và khối được gắn nhãn, bạn có thể mã bất kỳ thuật toán nào mà không bị mất hiệu lực . Tại sao mọi người không đọc văn học, thay vì sao chép những gì C đã làm? Grrr.

+0

Đây không phải là điều _break-to-dán nhãn-block_ mà bạn đã đề cập chính xác những gì đang được đưa ra với tính năng PHP mới này? Tha thứ cho tôi nếu tôi sai –

+0

Tính năng mới nào? ĐI ĐẾN? GOTO sẽ đưa bạn đến một nhãn được đặt trong một số phần ngẫu nhiên của mã của bạn. Dấu gạch ngang * chỉ * cho phép ngắt từ bên trong một khối để thoát khỏi khối. –

+0

Vâng, tôi đoán rằng _break-to-label_ điều bạn đã đề cập là ** chính xác ** những gì được đồn đại sẽ được giới thiệu trong php6. Nó không hồi sinh GOTO. –