2013-10-30 17 views
5

Đối với chương trình Scala đầu tiên của tôi, tôi đang cố viết một tiện ích nhỏ sẽ chuyển đổi một tệp XML từ lược đồ này sang lược đồ khác.Cách trả lại Không có trong Scala

tôi bắt đầu viết một phương pháp mà sẽ cung cấp cho tôi những nội dung file:

def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = { 
    try 
    { 
     val source = scala.io.Source.fromFile(filename, encoding) 
     val contents = source.mkString 
     source.close() 
     return Some(contents) 
    } 
    catch 
    { 
     return None 
    } 

    } 

Nhưng nó không biên dịch. Tôi nhận lại "giá trị áp dụng không phải là thành viên của Không có gì" và "giá trị isDefinedAt không phải là thành viên của Không có gì" dưới dạng thông báo lỗi từ dòng return None.

Tất cả các ví dụ tôi có thể tìm thấy trả lại tùy chọn Sử dụng kết hợp, nhưng điều này không có ý nghĩa ở đây. Tôi chỉ muốn không thất bại nếu tôi không thể đọc tập tin vì lý do nào đó.

Tôi nên làm gì trong trường hợp này? Có một mô hình để làm điều này ở Scala?

Trả lời

5

Có tất cả khoảng "catch".

Trong scala nó là nghĩa vụ phải được như thế này để làm cho nó biên dịch:

def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = { 
    try { 
     val source = scala.io.Source.fromFile(filename, encoding) 
     val contents = source.mkString 
     source.close() 
     Some(contents) 
    } catch { 
     case x: IOException => None 
     case x => errorHandler(x) // if any other exception 
    } 
    } 

    def errorHandler(e: Any) = None // put some logic here.. 

Vì vậy, sử dụng:

catch { case: x:ExceptionType ={ .. handling .. }} 

Trong Scala catch là một chức năng chấp nhận một chức năng như là đối số. Vì vậy, có những gì bạn có khiếu nại về việc áp dụng chức năng. case cung cấp chức năng (PartialFunction) mà catch muốn. (Trong Tóm lại)

Lưu ý: Tất cả ngoại lệ là unchecked trong Scala thậm chí IOException.

+0

Nhưng tôi đồng ý với + Nicolas Rinaudo về phong cách - cho phép người gọi quyết định cách xử lý lỗi, bất kể nó là gì.Đôi khi, mặc dù, bạn cần phải xử lý một số công cụ trên bên gọi (như làm sạch bộ nhớ cache hoặc bất cứ điều gì để làm sạch), trước khi gửi lỗi trở lại cho người gọi. – ses

0

Hãy thử điều này:

def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = { 
try 
{ 
    val source = scala.io.Source.fromFile(filename, encoding) 
    val contents = source.mkString 
    source.close() 
    return Some(contents) 
} 
catch 
    { 
    case e:Exception=>{ 
     return None 
    } 

    } 

}

8

Trong trường hợp cụ thể (xử lý ngoại lệ) này, tôi muốn đề nghị sử dụng một Try để thay thế.

def loadFile(filename: String, encoding: String = "utf-8"):Option[String] = { 
    Try { 
     val source = scala.io.Source.fromFile(filename, encoding) 
     val contents = source.mkString 
     source.close() 
     return Some(contents) 
    }.toOption 
} 

Tôi sẽ khuyên bạn không nên bắt ngoại lệ. Bạn đang nuốt nguyên nhân gây ra lỗi bằng cách trả lại None: có phải là FileNotFoundException không? một tiêu chuẩn IOException? đã có một thông báo với lỗi (Unsupported encoding đến với tâm trí ...)?

Quy tắc chung của tôi là cho phép người gọi xử lý ngoại lệ. Nếu anh ta không quan tâm đến những lỗi chính nó, xử lý mọi thứ dễ dàng như:

Try {loadFile("test.txt")}.toOption 

Hơn thế nữa, kể từ khi Try có tất cả các phương pháp cần thiết, nó có thể được sử dụng trong một cho-hiểu theo một cách khá gọn gàng :

for(s <- Try {loadFile("test.txt")}; 
    i <- Try {s.toInt}) yield i 

này sẽ dẫn đến hoặc là một Success[Int] hoặc một Failure có chứa một ngoại lệ mô tả chính xác những gì đã xảy ra.

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