Làm thế nào để bắt nhiều ngoại lệ cùng một lúc trong Scala? Có cách nào tốt hơn trong C #: Bắt nhiều ngoại lệ cùng một lúc không?
Làm thế nào để bắt nhiều ngoại lệ cùng một lúc trong Scala? Có cách nào tốt hơn trong C #: Bắt nhiều ngoại lệ cùng một lúc không?
Câu trả lời:
Bạn có thể liên kết toàn bộ mẫu với một biến như thế này:
try {
throw new java.io.IOException("no such file")
} catch {
// prints out "java.io.IOException: no such file"
case e @ (_ : RuntimeException | _ : java.io.IOException) => println(e)
}
Xem Đặc tả Ngôn ngữ Scala trang 118 đoạn 8.1.11 được gọi là Các lựa chọn thay thế Mẫu.
Xem Khớp mẫu hình đã được Unleashed để tìm hiểu sâu hơn về đối sánh mẫu hình trong Scala.
Khi bạn có quyền truy cập vào các khả năng đối sánh mẫu đầy đủ của scala trong mệnh đề bắt, bạn có thể làm được nhiều điều:
try {
throw new IOException("no such file")
} catch {
case _ : SQLException | _ : IOException => println("Resource failure")
case e => println("Other failure");
}
Lưu ý rằng nếu bạn cần viết lại cùng một trình xử lý, bạn có thể tạo cấu trúc điều khiển của riêng mình cho điều đó:
def onFilesAndDb(code: => Unit) {
try {
code
} catch {
your handling code
}
}
Một số phương pháp như vậy có sẵn trong đối tượng scala.util.control.Exceptions . fail, failAsValue, xử lý có thể chỉ là những gì bạn cần
Chỉnh sửa: Trái ngược với những gì được nói bên dưới, các mẫu thay thế có thể bị ràng buộc, vì vậy giải pháp được đề xuất không cần thiết phải phức tạp. Xem giải pháp @agilesteel
Thật không may, với giải pháp này, bạn không có quyền truy cập vào trường hợp ngoại lệ mà bạn sử dụng các mẫu thay thế. Theo hiểu biết của tôi, bạn không thể ràng buộc vào một mẫu thay thế với trường hợp e @ (_ : SqlException | _ : IOException)
. Vì vậy, nếu bạn cần quyền truy cập vào ngoại lệ, bạn phải lồng ghép các trình kết hợp:
try {
throw new RuntimeException("be careful")
} catch {
case e : RuntimeException => e match {
case _ : NullPointerException | _ : IllegalArgumentException =>
println("Basic exception " + e)
case a: IndexOutOfBoundsException =>
println("Arrray access " + a)
case _ => println("Less common exception " + e)
}
case _ => println("Not a runtime exception")
}
Bạn cũng có thể sử dụng scala.util.control.Exception
:
import scala.util.control.Exception._
import java.io.IOException
handling(classOf[RuntimeException], classOf[IOException]) by println apply {
throw new IOException("foo")
}
Ví dụ cụ thể này có thể không phải là ví dụ tốt nhất để minh họa cách bạn có thể sử dụng nó, nhưng tôi thấy nó khá hữu ích trong nhiều trường hợp.
Đây là cách duy nhất cho tôi, vượt qua khó khăn sbt clean coverage test coverageReport
mà không ném ra ngoại lệ phân tích cú pháp khó chịu ...
try {
throw new CustomValidationException1(
CustomErrorCodeEnum.STUDIP_FAIL,
"could be throw new CustomValidationException2")
} catch {
case e
if (e.isInstanceOf[CustomValidationException1] || e
.isInstanceOf[CustomValidationException2]) => {
// run a common handling for the both custom exceptions
println(e.getMessage)
println(e.errorCode.toString) // an example of common behaviour
}
case e: Exception => {
println("Unknown error occurred while reading files!!!")
println(e.getMessage)
// obs not errorCode available ...
}
}
// ...
class CustomValidationException1(val errorCode: CustomErrorCodeEnum, val message: String)
class CustomValidationException2(val errorCode: CustomErrorCodeEnum, val message: String)
sbt clean coverage test coverageReport
tại thời điểm viết bài ... github.com/scoverage/sbt-scoverage/issues/257