2008-09-11 35 views
22

Nhà phát triển có nên tránh sử dụng continue trong C# hoặc tương đương của nó bằng các ngôn ngữ khác để buộc lặp lại tiếp theo của vòng lặp không? Các đối số cho hoặc chống trùng lặp với các đối số về Goto?Tiếp tục được coi là có hại?

+1

Điều này buộc phải gây ra một cuộc chiến tranh giữa hai phe. Đây là một quyết định cá nhân, và có rất nhiều tranh luận và chống lại điều đó có thể được tìm thấy ở nơi khác. –

+1

Các câu trả lời cho đến nay là khá một chiều và tôi đã nhìn thấy ít nhất hai đối số mà tôi chưa bao giờ nghĩ đến hoặc thấy ở nơi khác. – brian

Trả lời

79

Tôi nghĩ rằng không nên được sử dụng hơn tiếp tục!

Quá lâu tôi đi qua mã như:

for (...) 
{ 
    if (!cond1) 
    { 
     if (!cond2) 
     { 
      ... highly indented lines ... 
     } 
    } 
} 

thay vì

for (...) 
{ 
    if (cond1 || cond2) 
    { 
     continue; 
    } 

    ... 
} 

Sử dụng nó để làm cho mã dễ đọc hơn!

+0

hoặc thậm chí: cho (...) { nếu (cond1 || cond2) tiếp tục; ... } tôi sử dụng nó như thế này tất cả các thời gian, có breakout của bạn trên cùng một dòng – johnc

+0

Chết tiệt, rằng bình luận trên sẽ đã làm việc tốt hơn với một ngắt dòng làm việc, điểm là giữ if (cond1 || cond2) tiếp tục; trên một dòng – johnc

+0

Trong perl, nó sẽ là 'next if cond1 || cond2; ' –

2

Tôi không nghĩ tiếp tục bao giờ có thể là khó khăn như goto kể từ khi tiếp tục không bao giờ di chuyển thực hiện của khối mã mà nó đang ở trong.

23

continue bất kỳ có hại nhiều hơn, chẳng hạn, break?

Nếu có, trong phần lớn các trường hợp mà tôi gặp phải/sử dụng nó, tôi thấy nó làm cho mã rõ ràng hơn và ít giống như spaghetti hơn.

+0

Nếu và chỉ khi RAII được sử dụng. Dấu ngắt và tiếp tục có thể gây rò rỉ bộ nhớ hoặc tệ hơn. – Fox

+4

@Fox: Đó là lỗi của bất kỳ ai đã tạo ra một mớ hỗn độn của quyền sở hữu đối tượng/cuộc đời. Không tiếp tục hoặc phá vỡ. –

+0

@LightnessRacesinOrbit hoàn toàn đồng ý. Hầu hết các nhóm lập trình tốt chỉ xảy ra để mã hóa các quy tắc như vậy. – Fox

12

Bạn có thể viết mã tốt có hoặc không tiếp tục và bạn có thể viết mã xấu có hoặc không có tiếp tục. Có thể có một số chồng lên nhau với các đối số về goto, nhưng theo như tôi lo ngại việc sử dụng tiếp tục tương đương với việc sử dụng câu lệnh ngắt (trong vòng lặp) hoặc câu lệnh trả về từ bất kỳ đâu trong thân phương thức - nếu được sử dụng đúng cách có thể đơn giản hóa mã (ít có khả năng chứa lỗi, dễ bảo trì hơn).

0

Tiếp tục là một chức năng thực sự hữu ích trong hầu hết các ngôn ngữ, bởi vì nó cho phép các khối mã bị bỏ qua trong một số điều kiện nhất định.

Một giải pháp thay thế sẽ là sử dụng các biến boolean trong câu lệnh if, nhưng chúng sẽ cần được đặt lại sau mỗi lần sử dụng.

0

tiếp tục cảm thấy sai với tôi. phá vỡ đưa bạn ra khỏi đó, nhưng tiếp tục dường như chỉ là spaghetti.

Mặt khác, bạn có thể mô phỏng tiếp tục ngắt (ít nhất là bằng Java).

for (String str : strs) contLp: { 
    ... 
     continue contLp; 
    ... 
} 

tiếp tục có thể hữu ích trong một số trường hợp, nhưng nó vẫn cảm thấy bẩn đối với tôi.

for (char c : cs) { 
    final int i; 
    if ('0' <= c && c <= '9') { 
     i = c - '0'; 
    } else if ('a' <= c && c <= 'z') { 
     i = c - 'a' + 10; 
    } else { 
     continue; 
    } 
    ... use i ... 
} 
+0

Tôi đồng ý. Đối với tôi, nó có vẻ như là thủ tục. –

1

goto có thể được sử dụng làm tiếp tục chứ không phải ngược lại.

Bạn có thể "goto" ở bất kỳ đâu, do đó, điều khiển dòng chảy tùy ý.

Do đó tiếp tục, không gần như có hại.

+1

Không, [bạn không thể "goto" "ở bất kỳ đâu"] (http://stackoverflow.com/questions/7334952/will-using-goto-leak-variables). –

5

Nếu tiếp tục gây ra sự cố với khả năng đọc, thì rất có thể bạn có vấn đề khác. Ví dụ, một lượng lớn mã bên trong vòng lặp for. Nếu bạn phải viết lớn cho vòng lặp, tôi sẽ cố gắng dính vào sử dụng tiếp tục gần với đầu vòng lặp for. Nếu không, một tiếp tục chôn sâu ở giữa một vòng lặp for có thể dễ dàng bị bỏ qua.

7

Không có từ khóa có hại. Chỉ có sử dụng có hại cho họ.

Goto không có hại cho mọi người, không tiếp tục. Họ cần phải được sử dụng cẩn thận, đó là tất cả.

+0

Điều này khiến tôi suy nghĩ "việc sử dụng goto không độc hại là gì?". Chắc chắn có một câu hỏi StackOverflow cho rằng: http://stackoverflow.com/questions/24451/goto-usage – thomasrutter

4

Tôi thích sử dụng tiếp tục ở đầu vòng để xử lý đơn giản nếu điều kiện.

Với tôi, nó làm cho mã dễ đọc hơn vì không có thêm lồng và bạn có thể thấy rằng tôi đã xử lý rõ ràng các trường hợp này.

Đây có phải là lý do giống như tôi sử dụng goto không? Có lẽ. Tôi sử dụng chúng cho dễ đọc vào những thời điểm và để ngăn chặn việc lồng mã nhưng tôi thường sử dụng chúng nhiều hơn để dọn dẹp/xử lý lỗi.

1

Những người khác đã ám chỉ nó ... nhưng tiếp tục và ngắt được thực thi bởi trình biên dịch và có quy tắc được liên kết của riêng chúng. Goto không có giới hạn như vậy, mặc dù hiệu ứng ròng có thể là gần như giống nhau, trong một số trường hợp.

Tôi không xem xét tiếp tục hoặc phá vỡ để có hại cho mỗi se, mặc dù tôi chắc chắn hoặc là có thể được sử dụng kém theo cách mà có thể làm cho bất kỳ gag lập trình lành mạnh.

+0

'tiếp tục và phá vỡ được thực thi bởi trình biên dịch và có quy tắc liên quan của riêng họ. Goto không có những hạn chế như vậy, Er, thế thì sao? Bạn có nghĩ rằng 'goto' phá vỡ các quy tắc phạm vi? Bởi vì [đó là một huyền thoại] (http://stackoverflow.com/questions/7334952/will-using-goto-leak-variables) ... –

+0

@LightnessRacesinOrbit - liên kết đến bài đăng của bạn về việc sử dụng goto trong C++ rất hấp dẫn nhưng cách chi tiết hơn mức tôi đã nghĩ!Rõ ràng tôi đã không chính xác để đề nghị goto có vài quy tắc biên dịch về việc sử dụng nó, nhưng tôi nghĩ rằng tôi có ý định là tiếp tục và phá vỡ đi đến những nơi được xác định trong vòng lặp gần nhất mà thường có thể được xác định bằng cách thụt lề mã - nói một cách lỏng lẻo phá vỡ bạn nhìn xuống và tiếp tục bạn nhìn lên. – Nij

0

Tôi tin rằng đối số cuối cùng chống lại tiếp tục là nó làm cho nó khó khăn hơn để PROVE rằng mã là chính xác. Điều này chứng minh theo nghĩa toán học. Nhưng nó có thể không quan trọng với bạn bởi vì không ai có tài nguyên để 'chứng minh' một chương trình máy tính phức tạp đáng kể.

Nhập các công cụ phân tích tĩnh. Bạn có thể làm cho mọi thứ khó khăn hơn đối với họ ...

Và goto, có vẻ như là một cơn ác mộng với cùng lý do nhưng ở bất kỳ vị trí ngẫu nhiên nào trong mã.

+1

Nói chung là phá vỡ và tiếp tục tránh sự cần thiết cho một trong hai biến auxilary hoặc trùng lặp mã. Do đó, họ nên làm cho nó dễ dàng hơn để chứng minh mã. Không phải mã prooving đó là thứ tôi có thể thử. –

+0

Không, [không phải "bất kỳ vị trí ngẫu nhiên nào trong mã"] (http://stackoverflow.com/questions/7334952/will-using-goto-leak-variables). Có lẽ bạn đang nghĩ đến 'longjmp', đó là ** không ** giống như' goto'. –

1

Tôi muốn nói có. Với tôi, nó chỉ phá vỡ 'dòng chảy' của một đoạn mã được viết trôi chảy.

Một đối số khác cũng có thể là nếu bạn tuân thủ các từ khóa cơ bản được hỗ trợ bởi hầu hết các ngôn ngữ hiện đại thì luồng chương trình của bạn (nếu không phải là logic hoặc mã) có thể được chuyển sang bất kỳ ngôn ngữ nào khác. Có một từ khóa không được hỗ trợ (tức là, tiếp tục hoặc goto) sẽ phá vỡ điều đó.

Nó thực sự là một sở thích cá nhân, nhưng tôi chưa bao giờ phải sử dụng nó và không thực sự coi đó là một tùy chọn khi tôi viết mã mới. (giống như goto.)

2

Nếu bạn đang lặp qua bất kỳ loại tập hợp kết quả nào và thực hiện các thao tác trên kết quả đã nêu, ví dụ: trong mỗi kết quả, và nếu một kết quả cụ thể gây ra sự cố, một lỗi dự kiến ​​(thông qua try-catch), ghi nhật ký nó và chuyển sang kết quả tiếp theo thông qua tiếp tục. Tiếp tục đặc biệt hữu ích, imo, đối với các dịch vụ không giám sát thực hiện công việc vào giờ lẻ, và một ngoại lệ không ảnh hưởng đến số lượng bản ghi x khác.

3

Tôi muốn nói: "nó phụ thuộc".

Nếu bạn có mã vòng lặp hợp lý nhỏ (nơi bạn có thể nhìn thấy toàn bộ vòng lặp mã mà không cần cuộn) thường là ok để sử dụng tiếp tục. Tuy nhiên, nếu thân chuông lớn (ví dụ do chuyển đổi lớn), và có một số mã theo dõi (nói bên dưới công tắc), bạn có thể dễ dàng giới thiệu lỗi bằng cách thêm tiếp tục và do đó bỏ qua mã đó đôi khi.Tôi đã gặp phải điều này trong trái tim của một thông dịch viên bytecode, ở đó một số mã thiết bị đo đạc đôi khi không được thực hiện do tiếp tục trong một số trường hợp-chi nhánh.

Đây có thể là trường hợp được tạo ra một cách giả tạo, nhưng tôi thường cố gắng tránh tiếp tục và sử dụng if (nhưng không lồng quá sâu như trong mã mẫu của Rob).

1

Theo như lập trình viên này có liên quan, Lồng nhau nếu/else được coi là có hại.

2
  1. Sử dụng tiếp tục vào đầu của một vòng lặp để tránh lặp lại qua các yếu tố không cần thiết là không có hại và có thể rất hữu ích, nhưng sử dụng nó ở giữa ifs lồng nhau và elses có thể biến mã vòng lặp vào một mê cung phức tạp , để hiểu và xác nhận.

  2. Tôi nghĩ việc tránh sử dụng nó cũng là kết quả của sự hiểu lầm ngữ nghĩa. Những người không bao giờ nhìn thấy/viết 'tiếp tục' từ khóa trên mã của họ, khi nhìn thấy một mã với tiếp tục có thể giải thích nó như là "sự tiếp tục của dòng chảy tự nhiên". Nếu thay vì tiếp tục, chúng tôi đã có kế tiếp, ví dụ, tôi nghĩ nhiều người sẽ đánh giá cao tính năng con trỏ có giá trị này.

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