Quyết định cho các trường hợp ngoại lệ không được kiểm tra trong Scala


17

Là một lập trình viên java, tôi luôn bị chỉ trích về Ngoại lệ không được kiểm tra. Hầu hết các lập trình viên sử dụng nó như một lộ trình để dễ dàng mã hóa chỉ để tạo ra rắc rối sau này. Ngoài ra, các chương trình (mặc dù không gọn gàng) với các ngoại lệ được kiểm tra rất mạnh mẽ so với các đối tác không được kiểm tra.

Đáng ngạc nhiên ở Scala, không có gì gọi là Ngoại lệ được kiểm tra. Tất cả các Java được kiểm tra và bỏ chọn đều không được chọn trong Scala.

Động lực đằng sau quyết định này là gì? Đối với tôi, nó mở ra một loạt các vấn đề khi sử dụng bất kỳ mã bên ngoài nào. Và nếu tình cờ tài liệu kém, nó sẽ dẫn đến KILL.


11
Là một lập trình viên Java, tôi luôn bị chỉ trích về các ngoại lệ được kiểm tra. Mã không gọn gàng là không bao giờ mạnh mẽ.
Michael Borgwardt

Câu trả lời:


28

Các trường hợp ngoại lệ được kiểm tra chủ yếu được coi là một thất bại. Lưu ý rằng không có ngôn ngữ nào được tạo sau khi Java chấp nhận chúng. Xem http://www.artima.com/intv/handcuffs2.html , http://googletesting.blogspot.ru/2009/09/checked-exceptions-i-love-you-but-you.html , http: / /www.mindview.net/Etc/Discussions/CheckedExceptions , v.v.

Cụ thể, chúng không thể so sánh được (ngoại trừ bằng cách hoàn nguyên throws Exception).

Trong Scala, bạn có một tùy chọn tốt hơn: sử dụng các loại đại số cho các giá trị trả về, chẳng hạn như Option[T], Either[Exception, T]loại của riêng bạn khi bạn muốn người dùng xử lý các trường hợp cụ thể (ví dụ thay vì

def foo: Int // throws FileNotFoundException, IllegalStateException

bạn có

sealed trait FooResult
case class Success(value: Int) extends FooResult
case class FileNotFound(file: File) extends FooResult
case object IllegalState extends FooResult

def foo: FooResult

và người tiêu dùng bây giờ được yêu cầu xử lý tất cả các kết quả)

Để xử lý mã bên ngoài không có ngoại lệ, bạn có scala.util.control.exceptionhoặc scala.util.Try(bắt đầu với Scala 2.10).


4
Không bao giờ hiểu hầu hết mọi người không xử lý đối số ngoại lệ được kiểm tra . Hầu hết mọi người không phải là nhà phát triển tốt. Tôi đảm bảo rằng hầu hết các nhà phát triển sẽ không xử lý kết quả lỗi nào. Trên thực tế, try..catchcó vẻ dễ đọc hơn nhiều if. Hơn nữa tôi cũng có thể đảm bảo rằng hầu hết các nhà phát triển đó sẽ không viết mã trả về kết quả lỗi - quá phức tạp trong Scala - bạn thậm chí không thể quay lại từ một hàm bất cứ khi nào bạn muốn (giống như trong Pascal)
Pijusn

5
Tôi thấy bạn bình luận khó hiểu và thiếu bằng chứng, @Pius. Trong Scala, việc chọn Tùy chọn làm kiểu trả về có thể dẫn đến kết quả khớp mẫu thay vì các câu lệnh If . Trả lại Không hơn là Một số trong phong cách đó là tầm thường, không phức tạp. Các nhà phát triển ít hiểu biết hơn có thể không chọn viết các hàm trả về các kiểu đại số nhưng đó là một điều khác. Cuối cùng, bạn cũng có thể trở lại từ một chức năng bất cứ khi nào bạn muốn - đơn giản là không đúng sự thật.
itbruce

7

Các ngoại lệ được kiểm tra trong Java không phải là một điều xấu. Tất nhiên các ADT có thể là lựa chọn tốt hơn cho Scala nhưng trong Java, các ngoại lệ được kiểm tra có vị trí của chúng và đối số mã gọn gàng chỉ là vô nghĩa cho dù có bao nhiêu blog lặp lại nó. Về cơ bản nó nói rằng bạn nên vui vẻ bỏ qua các điều kiện khắc nghiệt và có thể sửa chữa có thể xảy ra trong hệ thống của mình, bởi vì hệ thống loại vít, mã đẹp làm cho hệ thống của bạn tự động mạnh mẽ. Lý do như vậy cũng giải thích lý do tại sao rất nhiều lập trình viên Java tự nguyện chuyển mã của họ thành XML (Spring, Maven, v.v. Tôi bỏ lỡ phần khá ở đây).

Lý do thiếu các trường hợp ngoại lệ được kiểm tra trong Scala do M. Oderky đưa ra dưới đây http://www.scala-lang.org/old/node/8787.html không có gì đáng ngạc nhiên và có ý nghĩa.

Vấn đề với các ngoại lệ được kiểm tra được thể hiện tốt nhất bằng phương pháp bản đồ trong danh sách:

def map[B](f: A => B): List[B]

Làm cách nào để chú thích bản đồ với @throw? Nếu bản đồ không nhận được chú thích @throw thì có lẽ bạn không thể vượt qua bất kỳ chức năng nào có @throw. Điều đó sẽ giới thiệu những hạn chế và phân biệt rườm rà cho những cách sử dụng bản đồ. Mọi thứ sẽ tốt hơn nếu chúng ta có thể nói bằng cách nào đó bản đồ đó ném ra tất cả các ngoại lệ mà đối số chức năng của nó ném ra. Có một số hệ thống hiệu ứng có thể diễn tả điều này, nhưng cho đến nay mọi ký hiệu tôi thấy đều quá nặng.

Lukas Rytz đang thực hiện một số nghiên cứu về các hệ thống hiệu ứng nhẹ có thể được sử dụng để thể hiện loại bản đồ và các chức năng phổ biến khác một cách ngắn gọn và chính xác. Đó là nghiên cứu, vì vậy hiện tại vẫn chưa rõ chúng ta sẽ thành công ở mức độ nào và bao nhiêu trong số đó có thể được đưa vào Scala. Lý tưởng nhất là chúng ta sẽ có thể thêm nó vào một lúc nào đó dưới dạng một hệ thống loại tùy chọn. Nhưng đó là quá sớm để đưa ra dự đoán cụ thể.

Chúc mừng

Không chắc chắn nhưng tôi nghĩ rằng lambdas Java 8 cũng bị hạn chế đối với các ngoại lệ không được kiểm tra.Các phương thức trong hầu hết (tất cả?) Các giao diện chức năng mới trong JDK 8 ( java.util.function.*) cũng không khai báo các ngoại lệ không được kiểm tra.


2

Nếu bạn muốn đạt được hiệu quả, bạn phải từ bỏ .. độ chính xác / kiểm soát <- Tôi cần một từ tốt hơn cho điều đó.

Scala nằm ở phía trên cùng cho đến khi trừu tượng đi. Nếu một trong những mục tiêu của Scala là loại bỏ mã nồi hơi phiền phức, thì một nơi rõ ràng để xem xét là xử lý ngoại lệ của Java. Nếu bạn muốn viết mã nhanh trong java, chỉ cần tiếp tục ném ngoại lệ đã kiểm tra của bạn cho đến khi chúng nhấn main()và thực sự không được kiểm tra.

Tôi không biết liệu tôi có hiểu chính xác những gì bạn hỏi không nhưng đây là lý do rõ ràng nhất theo quan điểm của tôi.

Vâng, tôi đã làm một chút tìm kiếm và ai đó đã viết về bi kịch của ngoại lệ kiểm tra .

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.