Я пытаюсь вызвать этот метод set
документально here, в библиотеке Java jOOQ, с подписью:Почему Scala не использует здесь неявное преобразование?
<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)
Update - О примере Виниций в
Вместо того, чтобы попытаться объяснить это в комментариях, вот демонстрация того, что не существует неявное преобразование вызывается, когда вы используете тип с коварианта параметр, такой как 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")
}
Вы увидите, что он вызывает тест, но никогда не неявное преобразование из 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]
Хорошо, спасибо. Я понимаю разницу дисперсий между List и ArrayList, но, к сожалению, добавление [Integer] в этом случае не очень хорошо. Это произойдет слишком много и сделает код уродливым. Я хотел бы знать, почему неявный не используется. –
Я приму этот ответ, если найду что-нибудь в спецификации документов или языка, в которой говорится, почему он не считает неявным. Возможно, все параметры типа решаются до рассмотрения имплицитов. Если бы это было не так, он мог бы использовать 'ArrayList [Integer]' вместо 'ArrayList [Any]'. Вы, например, не совсем правы ... это не означает «принудительное неявное преобразование». Это запутанно в этом случае, потому что scala использует 'Integer' во время выполнения, потому что это' Int', но ваша тестовая функция просто получает «List [Any]». Вызывается неявная функция преобразования. –
@RobN, пожалуйста, помогите мне улучшить ваш ответ. Посмотрим, смогу ли я это сделать. Первый пример воспроизводит вашу ошибку. Компилятор не знает, как сопоставить (javageneric, Int) в (javageneric, T). Второй в Scala показывает неявное преобразование, заметим, что b преобразуется в java.lang.Integer. Я не знаю, где это находится в документации, я просто показал вам, экспериментируя. Если у вас есть пример, который может доказать, что я ошибаюсь, сделайте это. –