Tại sao các lỗi có tên là Exception Exception mà không phải là Lỗi Error trong ngôn ngữ lập trình?


45

Tôi đã suy nghĩ về điều đó khá lâu. Bản thân tôi không phải là người nói tiếng Anh bản địa nhưng tôi vẫn có nhiều năm kinh nghiệm lập trình và tôi luôn hỏi tôi điều này. Tại sao nó được đặt tên là Ngoại lệ nhưng không phải Lỗi vì chúng là lỗi.

Nó có thể được PageNotFoundErrorthay vì PageNotFoundException.


41
Không phải tất cả các tình huống đặc biệt là lỗi.
Andrew T Finnell

15
Đó là sự khác biệt giữa việc lái xe và đâm xe.
Kỹ sư thế giới

6
Bạn chỉ đang nói về việc đặt tên của các lớp ngoại lệ cụ thể? Sau đó lưu ý rằng trong một số hệ sinh thái, chúng được gọi là XYError- ví dụ, trong Python.

6
Xin lưu ý, Java có lớp Error, kế thừa từ throwable. Xem docs.oracle.com/javase/1.4.2/docs/api/java/lang/Error.html để biết thêm chi tiết. Bạn cũng có thể muốn kiểm tra danh mục "Các lớp con được biết trực tiếp".
luiscubal

Tôi muốn nói rằng câu hỏi hóc búa này không liên quan gì đến tiếng Anh. Đó là một cách phân loại hợp lý hơn trong bất kỳ ngôn ngữ nói nào mà bạn chọn thành thạo.
שינתיא אבישגנת

Câu trả lời:


59

Họ không cần phải có lỗi ở tất cả. Thực tế là trang không có thể chỉ là một sự thật thú vị chứ không phải là một lỗi thực tế. Chúng dường như được sử dụng như lỗi gần như mọi lúc, tôi thừa nhận. Nhưng đôi khi chúng được sử dụng để thoát ra khỏi các vòng lặp hoặc cho bạn biết rằng một chuỗi không phải là một số hợp lệ. Chúng có thể được sử dụng để giữ và trả lại một lượng lớn dữ liệu hữu ích - như là một phần của lợi nhuận khá bình thường. . trong này. "

Ngay cả một ngoại lệ con trỏ null có thể không có ý nghĩa nhiều với bạn. Bạn gọi mã của người khác và sau đó bắt ngoại lệ con trỏ null vì bạn biết rằng nó có khả năng làm nổ tung, in một thông báo cho biết đó là lỗi của ai, và tiếp tục và hoàn thành công việc của bạn.


27
Mặc dù việc sử dụng các cơ chế ngoại lệ làm luồng điều khiển có thể gây nhầm lẫn và tôi nghĩ nói chung là không tán thành.
ChaosPandion

11
@ChaosPandion: Phụ thuộc vào ngôn ngữ / văn hóa.
amara

11
@DocBrown: Tôi đã từng viết một bộ giải sudoku không tìm kiếm đệ quy mà quay lại khi không tìm thấy giải pháp trong lần thử hiện tại và thử lại với một giá trị khác; và khi một giải pháp được tìm thấy, nó sẽ ném một ngoại lệ có chứa giải pháp đó. Vấn đề ở đây là thất bại là tình huống "bình thường" và thành công là tình huống "đặc biệt"; và vì có nhiều điểm trong bộ giải mà nó tự gọi, không sử dụng ngoại lệ, bạn phải viết rất nhiều mẫu để kiểm tra xem cuộc gọi có trở lại từ tìm kiếm thành công hay từ tìm kiếm thất bại.
Lie Ryan

5
@Falcon: có, bạn chỉ có thể trả về giá trị 'đã hoàn thành', điều đó chỉ có nghĩa là mỗi khi bạn lặp lại, bạn sẽ phải làm: for (...) { if (func() == finished) { return finished; } else { itfailedsocheckanother(); }}nhưng xem xét rằng có nhiều điểm trong mã mà func () đang đệ quy, giải pháp không có ngoại lệ trở nên xấu hơn mỗi khi bạn thêm đệ quy. Đó là cái mà tôi gọi là lập trình sùng bái hàng hóa, về cơ bản nó là mô phỏng các ngoại lệ trong một ngôn ngữ đã có bởi vì nhà lãnh đạo giáo phái nói rằng "ngươi sẽ không sử dụng ngoại lệ".
Lie Ryan

8
@Falcon: Ah ... đối số "giống như Goto", các đối số đó hoạt động để nói rằng bạn không nên sử dụng các vòng lặp hoặc nếu các câu lệnh hoặc hàm gọi, bởi vì "tất cả chúng trông giống như gotos". Trở lại thành công với ngoại lệ chỉ là WTF nếu bạn liên kết ngoại lệ với lỗi. Đối với tôi, khi được sử dụng theo cách này, một khối thử bắt giống như "một lời hứa sẽ quay lại đây sau một hành trình dài", hành vi của thử-ngoại trừ + ném khá giống với các lệnh gọi hàm + trả về ngoại trừ những hành trình dài hơn có thể liên quan đến một ngăn xếp cuộc gọi rất sâu khi bạn hoàn thành nhiệm vụ tìm kiếm giải pháp.
Lie Ryan

21

Cơ chế của các trường hợp ngoại lệ không phải lúc nào cũng được sử dụng để báo hiệu lỗi. Các ngoại lệ được đưa ra khỏi các tình huống thông thường đòi hỏi một đường dẫn mã riêng để xử lý, bao gồm các lỗi. Ví dụ: người dùng cung cấp tên của tệp không tồn tại hoặc nhập chữ cái thay vì chữ số trong trường số là những tình huống đặc biệt cần xử lý đặc biệt, nhưng đây không phải là lỗi.

Trong một số môi trường lập trình, chẳng hạn như Java, các Errorđối tượng đặc biệt được cung cấp để báo cáo "lỗi thực sự", các tình huống mà một ứng dụng hợp lý không nên cố gắng xử lý. Các đối tượng này được phân phối bằng cùng một cơ chế được sử dụng để phân phối các ngoại lệ, nhưng chúng có ý nghĩa đặc biệt về các tín hiệu của các tình huống không thể phục hồi.


6

Tôi không có nghiên cứu từ nguyên về nguồn gốc của điều đó, nhưng tôi có thể hiểu rằng sử dụng thuật ngữ "Lỗi" có thể không chính xác trong mọi tình huống; cũng như gần nhưSharepointMaster đã đề cập, tốt hơn là nghĩ về lỗi và ngoại lệ được ném dưới dạng các thực thể tách biệt.

Khi bạn đang sử dụng ngôn ngữ lập trình cấp cao, sẽ hợp lý khi cho rằng một ngoại lệ luôn xảy ra do lỗi, mặc dù tôi cũng đồng ý với dasblinkenlight rằng ngay cả một ngoại lệ không phải lúc nào cũng là hậu quả của lỗi. Tôi, ví dụ, sử dụng các ngoại lệ để chấm dứt các chủ đề cộng tác.

Lần đầu tiên tôi thấy thuật ngữ "ngoại lệ" là trong hướng dẫn lắp ráp 80386. Tôi nhớ rằng khi tôi nhìn thấy nó trông tự nhiên ngay lập tức với tôi. Để gọi rằng một lỗi sẽ không chính xác, bởi vì không có lỗi trong hội; có những điều kiện đơn giản mà bộ xử lý không thể xử lý (nếu đó là lỗi - từ người lập trình, người dùng hoặc hệ thống - tốt, bộ xử lý hoàn toàn không tin vào điều đó). Tôi không biết liệu Intel có thực sự bắt nguồn từ thuật ngữ này hay không, nhưng có lẽ ...


3

Exception thường được sử dụng để đặt tên cho một sự kiện không đúng nhưng có thể được phục hồi, giống như một out_of_rangengoại lệ trong C ++, được ném khi truy cập một phần tử trong một vectơ hoặc mảng không tồn tại. Rõ ràng một sự kiện như vậy là không chính xác, nhưng nó xảy ra không có nghĩa là toàn bộ chương trình của bạn gặp sự cố.

Mặt khác, các lỗi thường được sử dụng để đặt tên cho một thứ gì đó sẽ làm hỏng mọi thứ, một cái gì đó như tràn ngăn xếp là một ví dụ về một sự kiện sẽ chấm dứt chương trình vì chương trình không thể xử lý nội bộ. Nói cách khác: một lỗi là chính, trong khi một ngoại lệ là tương đối nhỏ.


3

Tôi nghĩ rằng điều này có liên quan nhiều hơn đến "sự tiến hóa" của việc xử lý lỗi. Với các ngôn ngữ C / C ++ (trước khi xử lý ngoại lệ được thêm vào), nếu một chức năng thất bại, cách duy nhất để nói là thông qua giá trị trả về (ví dụ như HRESULTtrong win32). Vì vậy, thông thường bạn đã kết thúc việc bắt mã thoát của mỗi lệnh gọi hàm và thực hiện kiểm tra. Cách tiếp cận này làm cho mã lộn xộn hơn. Và nhiều lần các nhà phát triển sẽ tránh việc thêm các kiểm tra này vì sự lười biếng.

Với việc giới thiệu xử lý ngoại lệ, các nhà phát triển hiện có hai tùy chọn để đưa ra lỗi. Vì vậy, từ "ngoại lệ" đã được sử dụng để phân biệt lỗi với lỗi "trạng thái thoát". Sau một thời gian, xử lý ngoại lệ đã trở thành một cách phổ biến để truyền lỗi vì mã dễ đọc hơn, duy trì và có thể có một nơi duy nhất mà bạn có thể có logic xử lý lỗi.


2

Trong Python, chúng được đặt tên là ABCError Eg: KeyError, IndexError

http://docs.python.org/l Library / exceptions.html

Vì vậy, tôi nghĩ rằng nó phụ thuộc vào ngôn ngữ mà bạn sử dụng.


4
Đừng quên VB (cổ điển, không phải. Net). Trên Lỗi Goto đã được sử dụng. Và phát minh tuyệt vời nhất mọi thời đại "On Error Resume Next"
Kibbee

1
Trong Python, lỗi là một tập hợp con của các ngoại lệ. Có bốn trường hợp ngoại lệ tiêu chuẩn kế thừa từ Ngoại lệ nhưng không kế thừa từ StandardError: StopIteration, GeneratorExit, KeyboardInterrupt và SystemExit.
Dirk Holsopple

1

Khi xảy ra lỗi, hệ thống hoặc ứng dụng hiện đang thực thi sẽ báo cáo bằng cách đưa ra một ngoại lệ chứa thông tin về lỗi. Sau khi ném, một ngoại lệ được xử lý bởi ứng dụng hoặc bởi trình xử lý ngoại lệ mặc định.

Một lỗi gây ra một ngoại lệ chi tiết lỗi, vì vậy không phải tất cả mọi thứ đều là lỗi ngoại lệ nếu điều đó có ý nghĩa;), ví dụ, một ngoại lệ không thể hiểu được không phải là một lỗi mà là một ngoại lệ.

http://msdn.microsoft.com/en-us/l Library / system.exception.aspx


0

Trong lập trình iOS / Mac, chúng tôi có cả Ngoại lệ và Lỗi trong một ngôn ngữ.

Ít nhất trong môi trường đó, một ngoại lệ là "không thể phục hồi", trong khi một lỗi là "có thể phục hồi".

Ví dụ:

  • nếu bạn có một mảng với 10 mục và bạn cố gắng truy cập mục đó ở chỉ mục 30 - đó sẽ là một ngoại lệ. Bạn đã phạm một lỗi trong lập trình của bạn.
  • nếu bạn cố tải xuống một URL nhưng không có kết nối internet, đó là điều được mong đợi và bạn nên trình bày một số loại tin nhắn cho người dùng.

Các ngoại lệ thường làm hỏng ứng dụng của bạn, trong khi lỗi thường trả về nilvà một đối tượng lỗi (được trả về dưới dạng tham số của phương thức tham chiếu). Bạn có thể bắt ngoại lệ bằng một khối thử / bắt / cuối cùng nhưng không bao giờ nên sử dụng tính năng ngôn ngữ này - nếu có thể khôi phục từ một ngoại lệ theo bất kỳ cách nào, thì bạn không nên ném ngoại lệ nào cả (bạn nên quay lại một đối tượng lỗi thay thế).


2
Chà, nó hoàn toàn khác với những gì Ngoại lệ và Lỗi có ý nghĩa với các nhà phát triển khác sau đó!
Tarik

Mỗi ngôn ngữ là khác nhau, tôi đoán. Objective-C / Ca cao là một trong những ngôn ngữ lâu đời nhất được sử dụng tích cực (từ khoảng năm 1983), vì vậy có lẽ nó hơi lỗi thời. Tuy nhiên, nếu định nghĩa thay đổi từ cộng đồng này sang cộng đồng khác, điều quan trọng là phải biết điều đó.
Abhi Beckert

0

Một lỗi là một cái gì đó đã đi sai trong việc thực hiện chương trình. Thường thì điều này được giải quyết bằng cách đưa ra một ngoại lệ , nhưng

  • không có gì buộc một lập trình viên phải xử lý lỗi bằng cách đưa ra một ngoại lệ và
  • không có gì buộc một lập trình viên phải đưa ra ngoại lệ chỉ trong trường hợp có lỗi.

Lỗi là một khái niệm ngữ nghĩa : nó được áp dụng bởi lập trình viên hoặc người dùng, người đến với chương trình với kỳ vọng, để mô tả sự khác biệt giữa kỳ vọng và thực tế của họ. Chỉ một người có thể nói liệu một thói quen có ở trạng thái lỗi hay không.

Một ngoại lệ là một khái niệm cú pháp : đó là một cái gì đó trong chính chương trình, không phụ thuộc vào kỳ vọng của bất kỳ ai về những gì chương trình đó phải làm. Một thói quen hoặc không hoặc không đưa ra một ngoại lệ, bất kể mọi người nghĩ gì.


0

Ngoại lệ và lỗi là khác nhau.

Trường hợp ngoại lệ là các tình huống mà chương trình có thể khắc phục, chẳng hạn như bạn cố gắng mở tệp và nó không tồn tại, trong khi lỗi là tình huống mà chương trình không thể làm gì, như lỗi đĩa hoặc lỗi RAM.


0

Tăng và xử lý các ngoại lệ là các tính năng dòng điều khiển và tên của ngoại lệ phải tuân theo cách sử dụng có ý định. Người thiết kế mã và API nên tìm các sơ đồ đặt tên tốt và nhất quán.

Vì vậy, câu trả lời cho câu hỏi của bạn là: nó phụ thuộc vào bối cảnh và quan điểm.


0

Các ngoại lệ phát triển như một khái quát của các lỗi. Các ngôn ngữ lập trình đầu tiên bao gồm một cơ chế ngoại lệ là Lisp trong đầu những năm 1970. Có một bản tóm tắt hay trong Mô hình tiến hóa ngôn ngữ của Gabriel và Steele. Các ngoại lệ (chưa được gọi là ngoại lệ) xuất phát từ nhu cầu chỉ định hành vi của chương trình nếu xảy ra lỗi. Một khả năng là tạm dừng chương trình, nhưng điều này không phải lúc nào cũng hữu ích. Theo truyền thống, việc triển khai Lisp đã có một cách để sửa lỗi cho trình gỡ lỗi, nhưng đôi khi các lập trình viên muốn đưa vào xử lý lỗi trong chương trình của họ. Vì vậy, những năm 1960, việc triển khai Lisp đã có cách để nói rằng thực hiện điều này và nếu có lỗi xảy ra thì hãy thực hiện thay vào đó. Các lỗi ban đầu xuất phát từ các hàm nguyên thủy, nhưng các lập trình viên thấy thuận tiện khi cố tình kích hoạt một lỗi để bỏ qua một phần của chương trình và chuyển sang xử lý lỗi.

Năm 1972, hình thức xử lý ngoại lệ hiện đại ở Lisp đã xuất hiện trong MacLisp: throwcatch. Các phần mềm bảo tồn Nhóm liệt kê rất nhiều tài liệu về hiện thực Lisp sớm, bao gồm các MACLISP Reference Manual Revision 0 David trăng . Các nguyên thủy catchthrowđược ghi lại trong §5.3 tr.43.

catchlà chức năng LISP để thực hiện các lối thoát không cục bộ có cấu trúc. (catch x)đánh giá xvà trả về các giá trị của nó, ngoại trừ rằng nếu trong quá trình đánh giá x (throw y)nên được đánh giá, catchngay lập tức trả về ymà không cần đánh giá thêm x.

catchcũng có thể được sử dụng với một đối số econd, không được đánh giá, được sử dụng làm thẻ để phân biệt giữa các sản phẩm khai thác lồng nhau. (Càng)

throwđược sử dụng catchnhư là một cơ chế thoát không có cấu trúc.

(throw x)đánh giá xvà ném giá trị trở lại gần đây nhất catch.

(throw x <tag>)ném giá trị xtrở lại vào catchnhãn gần đây nhất có nhãn <tag>hoặc không ghi nhãn.

Trọng tâm là dòng điều khiển phi tiêu điểm . Đó là một hình thức của goto (một goto chỉ hướng lên), còn được gọi là một bước nhảy . Phép ẩn dụ là một phần của chương trình ném giá trị để trả về trình xử lý ngoại lệ và trình xử lý ngoại lệ bắt giá trị đó và trả về nó.

Hầu hết các ngôn ngữ lập trình ngày nay đều đóng gói thẻ và giá trị trong một đối tượng ngoại lệ và kết hợp cơ chế bắt với cơ chế xử lý.

Ngoại lệ không nhất thiết là lỗi. Chúng là một cách để thoát khỏi một khối mã và từ các khối xung quanh, thoát ra cho đến khi đạt được một trình xử lý ngoại lệ. Cho dù một điều như vậy được coi là một lỗi lỗi khắc nghiệt trong ý nghĩa trực quan là chủ quan.

Một số ngôn ngữ tạo ra sự khác biệt giữa các thuật ngữ lỗi Lỗi và lỗi ngoại lệ. Ví dụ, một số phương ngữ Lisp vừa throwđưa ra một ngoại lệ (luồng điều khiển cho người dùng, có nghĩa là thực hiện một lối thoát không cục bộ theo cách không chỉ ra rằng bất cứ điều gì đã xảy ra sai lầm) và signalgây ra lỗi (điều đó cho thấy rằng một cái gì đó đã bị lỗi sai và có thể gây ra một sự kiện gỡ lỗi).


-1

Bạn sẽ thấy nó được diễn giải khác nhau trong các triển khai ngôn ngữ lập trình khác nhau. Như dasblinkenlight đã nói rằng đó là quan điểm của java về việc phân định ranh giới giữa Lỗi và Ngoại lệ. Trong nhiều ngôn ngữ lập trình, các ngoại lệ là các vi phạm có thể được xử lý hoặc cho phép được tạo ra để chuyển sang mô-đun mã cao nhất có thể. Lỗi thường là các tình huống trong đó bộ chứa thời gian chạy ngôn ngữ của bạn xử lý (và nhiều trường hợp chỉ dừng thực thi).


-1

Một lỗi luôn luôn là một lỗi. Một ngoại lệ là một lỗi trong bối cảnh hiện tại. Đó là, một ngoại lệ là nhạy cảm bối cảnh. Một ví dụ về một ngoại lệ sẽ thêm ascii "a" vào số nguyên "1". Một lỗi có thể là một cái gì đó giống như sử dụng một toán tử không xác định như "+!" trong hầu hết các ngôn ngữ.

Một số languges sẽ cho phép bạn Xác định cách thoát khỏi tình huống nếu đó thực sự là những gì bạn muốn làm.

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.