我試圖調用此方法set
記錄here,Java庫jOOQ,有簽名:Scala爲什麼不在這裏使用隱式轉換?
<T> ... set(Field<T> field, T value)
這斯卡拉線是一個問題:
.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")
}
你會看到,它調用的測試,但從來沒有從String
「ABC」到Foo
隱式轉換。取而代之的是選擇T
,test[T]
,這是String
和Foo
之間的常見基類。當您使用Int
和Integer
時,它會選擇Any
,但這很令人困惑,因爲列表中Int
的運行時表示形式爲Integer
。所以它看起來像使用了隱式轉換,但它沒有。您可以通過打開斯卡拉提示驗證...
scala> :type StackOver1.test(List(new java.lang.Integer(1)), 2)
List[Any]
好吧,謝謝。我的確瞭解List和ArrayList之間的差異,但不幸的是在這種情況下添加[Integer]並不好。它會發生太多,並使代碼變得醜陋。我想知道爲什麼不使用隱式。 –
我會接受這個答案,如果我能找到的文檔或語言規範,說爲什麼不考慮隱含的東西。也許所有類型參數都是在考慮隱含之前決定的。如果不是這種情況,它可以使用'ArrayList [Integer]'而不是'ArrayList [Any]'。你的例子並不完全正確......它不會「強制隱式轉換」。這是因爲Scala是在運行時使用了'Integer'爲它的'Int',但你的測試功能簡單地得到一個'列表[任何]'混淆在這種情況下。沒有隱式轉換函數被調用。 –
@RobN,請幫我改進你的答案。讓我們看看我能否說清楚。第一個例子重現你的錯誤。編譯器完全不認識如何(javageneric,智力)配成(javageneric,T)。 Scala中的第二個顯示了隱式轉換的發生,注意到b轉換爲java.lang.Integer。我不知道這是在文件中,我只是通過實驗向你展示。如果你有一個可以證明我錯誤的例子,請做。 –