Tôi đang cố gắng để gọi phương thức set
này ghi nhận here, trong thư viện Java jOOQ, với chữ ký:Tại sao Scala không sử dụng chuyển đổi ngầm ở đây?
<T> ... set(Field<T> field, T value)
dòng Scala Đây là một vấn đề:
.set(table.MODIFIED_BY, userId)
MODIFIED_BY
là một Field<Integer>
đại diện cho cột bảng. userId
là Int
. Predef
có chuyển đổi tiềm ẩn từ Int
đến Integer
, vậy tại sao nó không sử dụng nó? Tôi có được điều này: Cập nhật
type mismatch; found: org.jooq.TableField[gen.tables.records.DocRecord,Integer]
required: org.jooq.Field[Any]
Note: Integer <: Any
(and org.jooq.TableField[gen.tables.records.DocRecord,Integer] <:
org.jooq.Field[Integer]), but Java-defined trait Field is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
- Giới thiệu về Ví dụ Vinicius của
Thay vì cố gắng giải thích điều này trong ý kiến, đây là một minh chứng rằng không có chuyển đổi ngầm được gọi là khi bạn sử dụng một loại với hiệp biến tham số, như List[+T]
. Hãy nói rằng tôi đặt mã này trong một tập tin, biên dịch, và chạy nó ...
case class Foo(str: String)
object StackOver1 extends App {
implicit def str2Foo(s: String): Foo = {
println("In str2Foo.")
new Foo(s)
}
def test[T](xs: List[T], x: T): List[T] = {
println("test " + x.getClass)
xs
}
val foo1 = new Foo("foo1")
test(List(foo1), "abc")
}
Bạn sẽ thấy rằng nó gọi kiểm tra, nhưng không bao giờ chuyển đổi ngầm từ String
"abc" để Foo
. Thay vào đó, hãy chọn một số T
cho test[T]
là lớp cơ sở chung giữa String
và Foo
. Khi bạn sử dụng Int
và Integer
nó chọn Any
, nhưng điều này gây nhầm lẫn vì biểu diễn thời gian chạy của Int
trong danh sách là Integer
. Vì vậy, có vẻ như nó đã sử dụng chuyển đổi ngầm, nhưng nó không. Bạn có thể xác minh bằng cách mở lời nhắc Scala ...
scala> :type StackOver1.test(List(new java.lang.Integer(1)), 2)
List[Any]
OK, cảm ơn. Tôi hiểu sự khác biệt không chính xác giữa Danh sách và ArrayList, nhưng tiếc là thêm [Integer] không tốt trong trường hợp này. Nó sẽ xảy ra quá nhiều và làm cho mã xấu xí. Tôi muốn biết tại sao ngầm định không được sử dụng. –
Tôi sẽ chấp nhận câu trả lời này nếu tôi có thể tìm thấy nội dung nào đó trong tài liệu hoặc thông số ngôn ngữ cho biết lý do tại sao nó không xem xét tiềm ẩn. Có lẽ tất cả các thông số kiểu được quyết định trước khi xem xét các hàm ý. Nếu không phải như vậy, nó có thể sử dụng 'ArrayList [Integer]' thay vì 'ArrayList [Any]'. Ví dụ bạn không hoàn toàn đúng ... nó không "ép buộc chuyển đổi ngầm". Thật khó hiểu trong trường hợp này bởi vì scala đang sử dụng 'Integer' khi chạy vì nó là' Int', nhưng hàm test của bạn đơn giản là nhận được một 'List [Any]'. Không có hàm chuyển đổi ngầm nào được gọi. –
@RobN, hãy giúp tôi cải thiện câu trả lời của bạn. Hãy xem nếu tôi có thể làm cho nó rõ ràng. Ví dụ đầu tiên tái tạo lỗi của bạn. Trình biên dịch doesnt biết làm thế nào để phù hợp (javageneric, Int) vào (javageneric, T). Điều thứ hai trong Scala cho thấy sự chuyển đổi ngầm xảy ra, chú ý rằng b được chuyển đổi thành java.lang.Integer. Tôi không biết nơi này là trong tài liệu hướng dẫn, tôi chỉ cho bạn thấy bằng cách thử nghiệm. Nếu bạn có một ví dụ có thể chứng minh cho tôi sai, xin vui lòng làm. –