2011-10-31 34 views
10

Sau khi sử dụng F # option nhập một lúc, tôi nhận ra rằng nó có thể được sử dụng để xử lý các trường hợp ngoại lệ. Tôi có thể sử dụng một trong hai option hoặc Exception trong các ví dụ sau:Tùy chọn so với Ngoại lệ trong xử lý ngoại lệ

  1. Các find chức năng từ Danh sách/Array/Seq module nâng KeyNotFoundException trong những trường hợp hiếm gặp, trong khi tương ứng tryFind đối tác trở None trong những tình huống này.
  2. Khi tôi quay ngược lại (khi giải quyết N-queens, Sudoku, vv), bất cứ khi nào chi nhánh không có giải pháp, tôi có thể tăng ngoại lệ và bắt nó sau hoặc trả lại Không để khớp với giá trị đó để quay lại. Những trường hợp đó xảy ra khá thường xuyên cho đến khi chúng tôi tìm ra giải pháp.

Hiển thị của tôi là option là phương pháp tiếp cận chức năng hơn, trong khi Exception thường được sử dụng trong nền tảng .NET.

Sự khác biệt giữa optionException trong xử lý ngoại lệ về khả năng sử dụng, hiệu suất, v.v ... là gì? Trong trường hợp nào sử dụng một kỹ thuật tốt hơn việc sử dụng kỹ thuật kia?

Trả lời

15

CLR làm cho hoạt động ném và bắt ngoại lệ cực kỳ tốn kém. Vì lý do này một mình, bạn nên chọn các cấu trúc như Option để báo cáo lỗi dự kiến. Nếu thất bại thật sự đặc biệt và gần như không thể phục hồi, hãy tiếp tục và ném một ngoại lệ. Nhưng như bạn lưu ý, những thứ như backtracking trong một tìm kiếm là không có ngoại lệ, và bạn sẽ thấy hiệu suất của bạn bị rất nhiều nếu bạn thực hiện chúng với các ngoại lệ.

Vì đây là tài sản của CLR, việc bạn đang ở trong F # có thực sự không quan trọng hay không. Sự hiểu biết của tôi là các thời gian chạy khác cho các ngôn ngữ giống như ML, ví dụ: ocaml, không có đặc điểm này, và do đó có thể sử dụng các ngoại lệ thường xuyên hơn cho luồng điều khiển.

+0

Thật vậy, tôi đã từng đo điều này và thấy rằng ngoại lệ C++ chậm hơn 6 lần so với OCaml và .NET chậm hơn 600 lần so với OCaml! –

5

Từ quan điểm lý thuyết. option là một cái gì đó mà bạn nên sử dụng trong những chức năng đó là tinh khiết từ điểm FP của xem (bạn có thể google về những gì là chức năng tinh khiết). Ngoại lệ là nhiều hơn về thế giới không tinh khiết (Giống như thế giới IO trong Haskell). Bây giờ từ quan điểm thực tế tôi sẽ đề nghị sử dụng option làm kiểu trả về khi logic của ứng dụng của bạn nói rằng giá trị có thể ở đó hoặc không thể là giá trị không có mặt là quy tắc ứng dụng hợp lệ. Ngoại lệ là một cái gì đó cần được nâng lên khi một cái gì đó xảy ra trong logic ứng dụng cho biết thực thi logic không chính xác hoặc một số trạng thái ứng dụng không chính xác mà không được dự kiến ​​là ngang bằng các quy tắc ứng dụng.

Từ hiệu suất ngoại lệ ném POV là đắt hơn (do ngăn xếp thư giãn - tìm trình xử lý ngoại lệ thích hợp - v.v) so với các loại tùy chọn trả về.

+0

Tôi không đồng ý với nhận xét về hiệu suất. Các loại tùy chọn có trọng lượng nhẹ hơn loại ngoại lệ (xem câu trả lời của @Sebastian Good). – pad

+0

Văn bản của tôi nói 'ngoại lệ sẽ xấu' .. có nghĩa là ngoại lệ không tốt trong hiệu suất – Ankur

+0

Xin lỗi, sai lầm của tôi vì không đọc kỹ :) – pad

4

Về khả năng sử dụng, tôi thích các tùy chọn trong F #.

  • Tùy chọn đóng gói trạng thái ngoại lệ cũng như trạng thái mong đợi. Điều này cho phép bạn deffer xử lý trạng thái ngoại lệ cho đến khi bạn cần trạng thái mong đợi.
  • Tùy chọn cũng có một số helper functions bạn phải tự viết cho mình các ngoại lệ.
  • Partial Active Patterns cho phép bạn xử lý nhiều trường hợp ngoại lệ rất rõ ràng với các tùy chọn.
  • Optional Paramaters trong F # được triển khai bằng Tùy chọn. Bản chất trì hoãn này tôi đã đề cập ở trên cho phép bạn không quan tâm những gì tạo ra trường hợp đặc biệt, miễn là người tiêu dùng có giá trị mặc định cho nó.

Tùy chọn là cách suy nghĩ cơ bản khác nhau về các trường hợp ngoại lệ và tôi tin rằng sẽ giúp làm cho F # trở nên đặc biệt.

+0

1 cho một câu trả lời rất chu đáo. Đó là những gì tôi muốn biết về cách sử dụng tùy chọn trong xử lý ngoại lệ. – pad

8

Câu hỏi của tôi là sự khác biệt giữa tùy chọn và ngoại lệ trong xử lý ngoại lệ về khả năng sử dụng, hiệu suất ... là gì?

Loại option cung cấp kiểm tra tĩnh mạnh hơn ngoại lệ, tăng cơ hội lỗi lập trình sẽ bị trình biên dịch bắt. Trả về không đặc biệt có thể nhanh hơn kết quả trả về Some nhưng trả về đặc biệt chậm hơn hàng trăm lần so với trả lại None.

Trong trường hợp nào sử dụng kỹ thuật tốt hơn kỹ thuật kia?

Bất cứ khi nào tôi viết mã như máy chủ và daemon cần tiếp tục chạy Tôi bắt được nhiều ngoại lệ nhất có thể và thay thế chúng bằng giá trị của loại hình công đoàn như option. Hệ thống kiểu tĩnh sau đó buộc tôi phải xử lý cả hai lợi nhuận đặc biệt và không đặc biệt trong hầu hết các trường hợp, làm cho nó dễ dàng hơn để viết mã mà sẽ không chết từ một ngoại lệ lan truyền bất ngờ.