Đây là một thiết lập đơn giản với hai đặc điểm, một lớp có tham số kiểu biến đổi được bao bọc bởi các đặc điểm trước đó và lớp thứ hai có tham số kiểu được bao bọc bởi lớp kia. Đối với cả hai lớp, một phương thức cụ thể có sẵn (thông qua bằng chứng tiềm ẩn) chỉ khi một trong hai đặc điểm làm nền tảng cho tham số kiểu. Đây biên dịch tốt:Scala: Bằng chứng ngầm cho lớp có tham số kiểu
trait Foo
trait ReadableFoo extends Foo {def field: Int}
case class Bar[+F <: Foo](foo: F) {
def readField(implicit evidence: F <:< ReadableFoo) = foo.field
}
case class Grill[+F <: Foo, +B <: Bar[F]](bar: B) {
def readField(implicit evidence: F <:< ReadableFoo) = bar.readField
}
Tuy nhiên, vì Bar
là hiệp biến trong F
, tôi không cần các F
tham số trong Grill
. Tôi chỉ cần yêu cầu rằng B
là một loại phụ của Bar[ReadableFoo]
. Này, tuy nhiên, thất bại:
case class Grill[+B <: Bar[_]](bar: B) {
def readField(implicit evidence: B <:< Bar[ReadableFoo]) = bar.readField
}
với lỗi:
error: Cannot prove that Any <:< this.ReadableFoo.
def readField(implicit evidence: B <:< Bar[ReadableFoo]) = bar.readField
Tại sao những bằng chứng tiềm ẩn không được đưa vào tài khoản?
Tôi không chắc chắn nếu <:
Kaito
@Kaito: Bạn có bất kỳ bằng chứng nào cho thấy '<: <' ''áp dụng' không có nghĩa là được gọi? Đó là [hành vi được ghi lại] (http://www.scala-lang.org/api/rc/scala/Predef$$$less$colon$less.html). Bạn có thể viết '(bar: Bar [ReadableFoo]). ReadField' và để cho chuyển đổi ngầm xuất hiện tự động, nhưng phiên bản của Sciss cảm thấy sạch hơn với tôi. –
@TravisBrown: Không. Nhưng tôi không thể tìm thấy dòng mà thực sự bằng lời nói về hành vi của hàm, chỉ là lời giải thích được thừa kế của đặc điểm trừu tượng Function1. Tôi đồng ý rằng nó tốt đẹp nhưng tôi không chắc chắn nếu hành vi đó có thể được dựa vào, nó cũng có thể ném một ngoại lệ trong phiên bản tiếp theo tôi nghĩ. – Kaito