2011-10-17 33 views
19

Tôi đã đọc và thử nghiệm với tính năng thử thách của phiên bản Scala 2.9 ... và tôi đã suy nghĩ về các khả năng. Tôi thực sự sẽ sử dụng nó để làm gì ngoài việc tiết kiệm một vài dòng mã?Các trường hợp sử dụng cho thử nghiệm của Scala 2.9 ... bắt tổng quát là gì?

Scala 2.9 Final Release Notes

+0

Tôi không chắc mình sẽ sử dụng nó .... nhưng bạn có thể sử dụng * any * (conforming) PartialFunction ... có xử lý lỗi thống nhất ở nơi khác không? (Nói 'ignoreTheseSillyClosableExceptions'.) Bên cạnh đó," nó chỉ là mát mẻ "mà Scala có thể diễn tả nó như thế ;-) –

+0

Để cảm hứng: Paul Phillips đã cung cấp một ví dụ động lực khi ông thực hiện điều này: http://www.scala-lang.org/node/8070 –

+3

Câu hỏi sẽ tốt hơn với ví dụ hoặc ít nhất là một liên kết. – ziggystar

Trả lời

24

Các trường hợp sử dụng là để có thể có xử lý suốt ứng dụng của bạn báo lỗi chung chung. Giả sử bạn muốn xử lý tất cả FileNotFoundException trong ứng dụng của mình bằng cách gửi e-mail cho quản trị viên. Trước đó, bạn sẽ phải làm điều đó như thế này:

// Globally 
val fileNotFound: PartialFunction[Throwable, Unit] = { 
    case e: FileNotFoundException => 
    // Create report and send the e-mail 
} 

// On each try-catch-block 
try { 
    // Open file 
} 
catch { 
    case fnf: FileNotFoundException => fileNotFound(fnf) 
} 

Bây giờ bạn chỉ cần làm:

try { 
    // Open file 
} catch fileNotFound 

này cũng có lợi thế tốt đẹp mà bạn có thể liên kết nhiều bộ xử lý ngoại lệ như vậy bằng cách sử dụng phương pháp orElse trên một phần chức năng:

val fileErrors = fileNotFound orElse endOfFile orElse invalidFormat 

Và sau đó chỉ cần sử dụng ở mọi nơi bạn cần xử lý ngoại lệ tệp. Trình xử lý lỗi như vậy có thể được kết hợp động dựa trên tệp cấu hình cho ứng dụng, ví dụ. Điều này là ít cồng kềnh hơn so với mô hình phù hợp ở khắp mọi nơi và gọi xử lý chính xác.

Một điều hữu ích có thể được pimped trên đầu trang của các chức năng một phần là nhà điều hành andAlso, hoạt động như một nhà điều hành trình tự trên hai chức năng một phần. Điều này sẽ hữu ích khi bạn muốn thực hiện một số lỗi xử lý cụ thể cho một khối try-catch cụ thể sau khi thực hiện xử lý lỗi chung.

implicit def pf2ops(pf: PartialFunction[Throwable, Unit]) = new { 
    def andAlso(localpf: PartialFunction[Throwable, Unit]) = new PartialFunction[Throwable, Unit] { 
    def apply(t: Throwable) = { 
     if (pf.isDefinedAt(t)) pf(t) 
     localpf(t) 
    } 
    def isDefinedAt(t: Throwable) = pf.isDefinedAt(t) || localpf.isDefinedAt(t) 
    } 
} 

Và sau đó bạn có thể làm điều này:

scala> try { 
    | throw new java.io.FileNotFoundException 
    | } catch fnf andAlso { 
    | case e: Exception => println("I don't know, but something is specific to this particular block.") 
    | } 
I don't know, but something is specific to this particular block. 

Tôi đoán bạn có thể chơi thêm với ngữ nghĩa chính xác và ý nghĩa (và tên) của andAlso.

+0

Câu trả lời hay - Tôi nghĩ phần andAlso là phần mà tôi đã bỏ lỡ. – Seth

7

Câu trả lời hay bởi axel22, nhưng tôi nghĩ lý do thực sự cho phần giới thiệu của nó là thứ gì đó khác. Việc xử lý try/catch/finally đã giới thiệu một trường hợp đặc biệt . Bạn đã sử dụng hàm một phần theo nghĩa đen, nhưng bạn không thể thay thế bằng hàm một phần. Bây giờ, catch chỉ nhận được một chức năng một phần và một trường hợp đặc biệt khác trong ngôn ngữ đã biến mất.

+0

Tôi thích câu trả lời này quá :) – Seth

+0

Điều này thực sự xác nhận lý do ban đầu của tôi - rằng đây chủ yếu là một tính năng "gọn gàng". – Seth

+0

Đồng ý - đó là nguyên tắc đồng nhất ở mức tốt nhất của nó - một cấu trúc tổng quát có khả năng sử dụng như một hệ quả. – axel22

Các vấn đề liên quan