Я пытаюсь вызвать этот set
метод, задокументированный здесь, в библиотека Java jOOQ с подписью:
<T> ... set(Field<T> field, T value)
Эта строка Scala представляет собой проблему:
.set(table.MODIFIED_BY, userId)
MODIFIED_BY
- это Field<Integer>
, представляющий столбец таблицы. userId
равно Int
. Predef
имеет неявное преобразование из Int
в Integer
, так почему же он его не использует? Я получаю это:
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)
Обновление - о примере Винисиуса
Вместо того, чтобы пытаться объяснить это в комментариях, вот демонстрация того, что неявное преобразование не вызывается, когда вы используете тип с ковариантным параметром, например List[+T]
. Допустим, я помещаю этот код в файл, компилирую и запускаю ...
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")
}
Вы увидите, что он вызывает test, но никогда не вызывает неявное преобразование String
"abc" в Foo
. Вместо этого он выбирает T
для test[T]
, который является общим базовым классом между String
и Foo
. Когда вы используете Int
и Integer
, он выбирает Any
, но это сбивает с толку, потому что время выполнения для Int
в списке равно Integer
. Похоже, что использовалось неявное преобразование, но этого не произошло. Вы можете проверить, открыв приглашение Scala ...
scala> :type StackOver1.test(List(new java.lang.Integer(1)), 2)
List[Any]