Điều đó có nghĩa là Tùy chọn [Không có gì] là loại phụ của Tùy chọn [Int] (do hiệp phương sai), phải không?
Đúng. Option[Nothing]
là Option[Int]
.
Nhưng với B>: A chúng tôi đã nói rằng B phải là siêu nhân ?! Vậy làm thế nào chúng ta có thể lấy lại Int?
Nó không phải là siêu kiểu. Nó chỉ yêu cầu A
dưới dạng giới hạn dưới. Điều này có nghĩa là bạn vẫn có thể vượt qua Int
đến getOrElse
nếu A
là Int
.
Nhưng điều đó không có nghĩa là bạn không thể chuyển trường hợp của một lớp con. Ví dụ:
class A
class B extends A
class C extends B
scala> Option(new B)
res196: Option[B] = Some([email protected])
scala> res196.getOrElse(new C)
res197: B = [email protected]
scala> res196.getOrElse(new A)
res198: A = [email protected]
scala> res196.getOrElse("...")
res199: Object = [email protected]
tôi vẫn có thể vượt qua một thể hiện của C
, vì C
có thể lên-cast để B
. Tôi cũng có thể vượt qua một loại cao hơn cây thừa kế, và thay vào đó, getOrElse
sẽ trả về loại đó. Nếu tôi chuyển loại không liên quan đến loại có trong số Option
, thì loại có giới hạn trên ít nhất sẽ được suy ra. Trong trường hợp trên, nó là Any
.
Vậy tại sao có giới hạn thấp hơn? Tại sao không có:
def getOrElse[B <: A](default: => B): B
này sẽ không làm việc vì getOrElse
phải hoặc trả lại A
đó là chứa trong Option
, hoặc mặc định B
. Nhưng nếu chúng tôi trả lại A
và A
không phải là B
, do đó, loại giới hạn không hợp lệ.Có lẽ nếu getOrElse
trở A
:
def getOrElse[B <: A](default: => B): A
này sẽ làm việc (nếu nó đã thực sự được xác định như vậy), nhưng bạn sẽ bị hạn chế bởi các loại-giới hạn. Vì vậy, trong ví dụ trên, bạn chỉ có thể vượt qua B
hoặc C
đến getOrElse
trên Option[B]
. Trong mọi trường hợp, đây không phải là cách nó nằm trong thư viện chuẩn.
Thư viện chuẩn getOrElse
cho phép bạn chuyển bất kỳ thứ gì cho nó. Giả sử bạn có Option[A]
. Nếu chúng tôi chuyển loại phụ của A
, thì nó sẽ được truyền lên A
. Nếu chúng tôi vượt qua A
, rõ ràng điều này là không sao. Và nếu chúng ta vượt qua một số loại khác, thì trình biên dịch sẽ thâm nhập giới hạn trên ít nhất giữa hai loại. Trong mọi trường hợp, đáp ứng B >: A
loại được ràng buộc.
Vì getOrElse
cho phép bạn chuyển bất kỳ thứ gì cho nó, nhiều người coi nó rất phức tạp. Ví dụ: bạn có thể có:
val number = "blah"
// ... lots of code
val result = Option(1).getOrElse(number)
Và điều này sẽ biên dịch. Chúng tôi sẽ chỉ có một số Option[Any]
có thể sẽ gây ra lỗi ở một nơi khác trên đường truyền.
Cảm ơn bạn, nhưng bạn có thể vui lòng cung cấp ví dụ về loại chúng tôi không thể chuyển sang res196.getOrElse ... hiện tại, với ví dụ này, tôi không thấy điểm có giới hạn thấp hơn. Hoặc tốt hơn để nói, bây giờ tôi không hiểu ý nghĩa của một loại là giới hạn thấp hơn ... – Marin
@Marin Bạn có thể chuyển bất kỳ loại nào thành 'getOrElse'. Xem chỉnh sửa của tôi. –
cảm ơn! Tôi nghĩ rằng tôi nhận được nó ngay bây giờ. – Marin