Đây là một chủ đề rất cũ nhưng là một chủ đề hay!
Đúng là việc chuyển đổi bất kỳ kết quả Không ngoại lệ nào của Try to Option sẽ dẫn đến một số ...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
... bởi vì Thử không phải về kiểm tra tính vô hiệu mà chỉ là một cách để xử lý các ngoại lệ về mặt chức năng.
Việc sử dụng Cố gắng bắt một ngoại lệ và chuyển đổi thành Tùy chọn để thuận tiện sẽ chỉ hiển thị Không có trong trường hợp ngoại lệ xảy ra.
scala> Try(1/0).toOption
res11: Option[Int] = None
Bạn muốn bảo tồn các giá trị có được từ Thử. Đó có thể là giá trị không.
Nhưng cũng đúng là lib tiêu chuẩn đôi khi khá khó hiểu ...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
Hành vi này hơi mâu thuẫn nhưng nó phản ánh cách sử dụng có chủ đích của cả Try và Option.
Bạn sử dụng cố gắng lấy bất cứ điều gì xuất hiện từ một biểu thức có thể tạo ra các ngoại lệ và bạn không quan tâm đến chính ngoại lệ đó.
Giá trị có thể xuất hiện rất có thể là giá trị rỗng. Nếu toOption đưa ra Không có, bạn không thể phân biệt giữa ngoại lệ và null , và điều đó không đẹp!
Độc lập, bạn sử dụng Option để gói gọn sự tồn tại hay không của một thứ gì đó. Vì vậy, trong trường hợp đó Some (null) là Không có, và điều đó có ý nghĩa, bởi vì null trong trường hợp đó đại diện cho sự vắng mặt của một cái gì đó. Không có sự mơ hồ ở đây.
Điều quan trọng cần lưu ý là trong mọi trường hợp, tính minh bạch của tham chiếu không bị phá vỡ vì .toOption không giống như Option ()
Nếu bạn thực sự cần thực thi cả an toàn ngoại lệ VÀ an toàn null, và mã của bạn thực sự không cần phân biệt giữa null và ngoại lệ , bạn chỉ cần kết hợp cả hai mô hình! Bởi vì tốt, đó là những gì bạn muốn, phải không?
Bạn có thể làm điều đó bằng một cách ...
scala> Try(Option(null)).getOrElse(None)
res23: Option[Null] = None
scala> Try(Option(3/0)).getOrElse(None)
res24: Option[Int] = None
scala> Try(Option(3)).getOrElse(None)
res25: Option[Int] = Some(3)
... hay cách khác ...
scala> Try(Option(null)).toOption.flatten
res26: Option[Null] = None
scala> Try(Option(3/0)).toOption.flatten
res27: Option[Int] = None
scala> Try(Option(3)).toOption.flatten
res28: Option[Int] = Some(3)
... hoặc người xấu xí nhất trong số họ ...
scala> Option(Try(null).getOrElse(null))
res29: Option[Null] = None
scala> Option(Try(3/0).getOrElse(null))
res30: Option[Any] = None
scala> Option(Try(3).getOrElse(null))
res31: Option[Any] = Some(3)