Khi nào sử dụng os.Exit () và hoảng loạn ()?


92

Ai đó có thể giải thích sự khác biệt chính giữa os.Exit()panic()và cách chúng được sử dụng trong thực tế trong cờ vây không?


11
Chỉ là một nhận xét hy vọng sẽ giúp ích cho việc đọc mã Go trong tương lai: Trong rất nhiều ví dụ, mã panicnày được sử dụng để thoát khi bị lỗi, hoàn toàn là do nó dễ hiểu và loại bỏ việc nhập bất kỳ gói nào khác. Điều này không có nghĩa là nó tốt, hoặc thực hành thành ngữ! . Nó chỉ là một thiết bị tiết kiệm không gian cho mã ví dụ. IRL dự phòng paniccho những tình huống rất đặc biệt.
Intermernet

1
Hm..tốt) đặc biệt là chữ viết tắt "IRL" - nó mới đối với tôi :) Bạn có thể giải thích cách hoảng loạn loại bỏ việc nhập gói không?
Timur Fayzrakhmanov

4
paniclà một nội trang. Khuyến nghị (tùy thuộc vào trường hợp) sử dụng một cái gì đó như os.Exit, log.Fatalv.v., sẽ trả về mã lỗi cho Hệ điều hành (luôn được khuyến nghị nếu có thể). Tất cả những thứ này đều liên quan đến việc nhập một gói và do đó làm "lộn xộn" mã ví dụ. Mã ví dụ chỉ nên được sử dụng để chứng minh giải pháp cho một vấn đề cụ thể. Có thể có các vấn đề khác với mã, làm cho mã phức tạp hơn nếu được trình bày đúng cách, và do đó làm giảm đi sự giải thích của câu trả lời được đưa ra. YMMV.
Intermernet

1
Ok, đã nhận nó) Big nhờ) tôi thấy có thêm một tên viết tắt của từ vựng của tôi :)!
Timur Fayzrakhmanov

2
NP, rất vui được trợ giúp và để tăng vốn từ vựng viết tắt của bạn :-)
Intermernet

Câu trả lời:


84

Trước hết, bất cứ khi nào bạn có câu hỏi "nó được sử dụng như thế nào trong thực tế", cách tốt để bắt đầu là tìm kiếm mã nguồn Go (hoặc bất kỳ cơ sở mã Go đủ lớn nào) và tài liệu gói để có câu trả lời.

Bây giờ, os.Exitpanichoàn toàn khác. panicđược sử dụng khi chương trình, hoặc một phần của nó, đã đạt đến trạng thái không thể khôi phục.

Khi panicđược gọi, bao gồm ngầm định các lỗi thời gian chạy, chẳng hạn như lập chỉ mục một lát ngoài giới hạn hoặc không xác nhận kiểu, nó sẽ ngay lập tức dừng thực thi chức năng hiện tại và bắt đầu giải nén ngăn xếp của quy trình, chạy mọi chức năng bị trì hoãn trong quá trình thực hiện. Nếu quá trình gỡ bỏ đó đạt đến đầu ngăn xếp của quy trình, chương trình sẽ chết.

os.Exitđược sử dụng khi bạn cần hủy bỏ chương trình ngay lập tức, không có khả năng khôi phục hoặc chạy câu lệnh dọn dẹp hoãn lại và cũng trả về mã lỗi (mà các chương trình khác có thể sử dụng để báo cáo những gì đã xảy ra). Điều này rất hữu ích trong các bài kiểm tra, khi bạn đã biết rằng sau một lần kiểm tra này không thành công, bài kiểm tra kia cũng sẽ thất bại, vì vậy bạn cũng có thể thoát ngay bây giờ. Điều này cũng có thể được sử dụng khi chương trình của bạn đã hoàn thành mọi thứ cần thiết và bây giờ chỉ cần thoát ra, tức là sau khi in thông báo trợ giúp.

Hầu hết thời gian bạn sẽ không sử dụng panic( errorthay vào đó bạn nên trả lại ) và bạn hầu như không bao giờ cần os.Exitngoài một số trường hợp trong các thử nghiệm và để kết thúc chương trình nhanh chóng.


9
"Điều này hữu ích trong các bài kiểm tra, khi bạn đã biết rằng sau khi bài kiểm tra này không thành công, bài kiểm tra kia cũng sẽ thất bại ..." Điều này có mùi của một mô hình chống thử nghiệm của các thử nghiệm phụ thuộc. Trong một bộ kiểm tra được viết tốt, mỗi bài kiểm tra là độc lập; kết quả của bất kỳ thử nghiệm đã cho không bao giờ được xác định kết quả của bất kỳ thử nghiệm nào khác.
gotgenes

1
@gotgenes Không nhất thiết. Nếu tôi có một bài kiểm tra rằng một hàm nhất định trả về một cấu trúc không phải nil và kiểm tra đó không thành công, thì tôi có thể hy vọng rằng tất cả các bài kiểm tra kiểm tra các giá trị của cấu trúc cũng sẽ thất bại. Đó là mã phụ thuộc, không phải các bài kiểm tra. (Điều đó nói rằng, tôi sẽ không sử dụng exittrong trường hợp đó, tôi chỉ mong đợi một đống lớn các xác nhận thất bại.)
David Moles

83

Trước hết, os.Exit()có thể được sử dụng để thoát khỏi chương trình một cách bình thường mà không gặp lỗi, và đừng lo lắng, vì vậy đó là một điểm phân biệt chính. Khác là sự hoảng sợ ở đâu đó có thể bị bắt và bỏ qua hoặc ghi lại bằng cách sử dụng recover.

Nhưng nếu chúng ta đang nói về một mã thoát sai, hãy nói:

Sử dụng panickhi có sự cố khủng khiếp, có thể là lỗi của lập trình viên đáng lẽ phải mắc trước khi đưa vào sản xuất. Đây là lý do tại sao nó in ngăn xếp.

Sử dụng os.Exit(errorCode)hoặc thứ gì đó tương tự nếu bạn muốn:

  1. kiểm soát mã thoát của chương trình cho mục đích viết kịch bản.

  2. muốn thoát có trật tự về một lỗi được mong đợi (ví dụ: lỗi người dùng nhập).

Vì vậy, về cơ bản sự hoảng loạn là dành cho bạn, mã thoát xấu là dành cho người dùng của bạn.


Cảm ơn rất hữu ích!)
Timur Fayzrakhmanov

14
"Vì vậy, về cơ bản sự hoảng loạn là dành cho bạn, mã thoát xấu là dành cho người dùng của bạn." <- Mẹo tuyệt vời
psousa 17/09/17

1
Chúng ta có thể nói rằng hoảng loạn () bằng cách nào đó liên quan đến lệnh gọi khẳng định () thông thường trong C đơn giản không? Chà .. Tôi biết tôi luôn xóa lệnh gọi xác nhận trước khi chuyển sang phiên bản sản xuất, tôi chỉ bật chúng khi thử nghiệm một tính năng mới. Những gì tôi đang nói là hầu hết thời gian tôi sử dụng khẳng định () để xác minh các bất biến mà tôi đoán phải giữ đúng trong mã của mình. Bạn có thấy cách sử dụng tương tự cho hoảng loạn () không? :-)
yves Baumes

7

Sự khác biệt chính là:

  1. os.Exit bỏ qua việc thực hiện chức năng hoãn lại.
  2. Với os.Exit, bạn có thể chỉ định mã thoát.
  3. panicđang kết thúc trong khi os.Exitthì không. (Có vẻ như các câu trả lời khác không đề cập đến điều này.)

Nếu bạn cần thực hiện chức năng hoãn lại, bạn không có lựa chọn nào khác ngoài panic. (Mặt khác, nếu bạn muốn bỏ qua việc thực thi chức năng hoãn lại, hãy sử dụng os.Exit.)

Nếu một hàm non-void được định nghĩa theo cách như vậy:

  1. hàm chứa rất nhiều nhánh
  2. tất cả các chi nhánh được kết thúc bằng returnhoặcpanic

Sau đó, bạn không thể thay thế panicbằng os.Exitnếu không trình biên dịch sẽ từ chối biên dịch chương trình, nói rằng "thiếu trả về ở cuối chức năng". (Ở đây Go rất ngớ ngẩn, thậm chí log.Panickhông kết thúc một hàm.)

Trong các điều kiện khác:

  1. Sử dụng panickhi có điều gì đó thực sự có dây xảy ra, ví dụ như lỗi logic lập trình.
  2. Sử dụng os.Exitkhi bạn muốn thoát ngay lập tức, với mã thoát được chỉ định.
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.