【发布时间】:2013-09-28 11:58:47
【问题描述】:
我正在尝试在 Java 库 jOOQ 中调用记录在 here 中的此 set 方法,并带有签名:
<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)
更新 - 关于维尼修斯的例子
这里没有尝试在 cmets 中解释这一点,而是演示了当您使用带有协变参数的类型时不会调用隐式转换,例如 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 的隐式转换。相反,它为test[T] 选择T,这是String 和Foo 之间的公共基类。当您使用Int 和Integer 时,它会选择Any,但这很令人困惑,因为列表中Int 的运行时表示是Integer。所以看起来它使用了隐式转换,但它没有。您可以通过打开 Scala 提示符来验证...
scala> :type StackOver1.test(List(new java.lang.Integer(1)), 2)
List[Any]
【问题讨论】:
标签: scala implicit jooq type-mismatch