Próbuję zadzwonić ta metoda set
udokumentowane here w bibliotece Java jOOQ, z podpisem:Dlaczego Scala nie używa tutaj konwersji niejawnej?
<T> ... set(Field<T> field, T value)
Linia ta Scala jest problem:
.set(table.MODIFIED_BY, userId)
MODIFIED_BY
jest Field<Integer>
reprezentujący kolumna tabeli. userId
to Int
. Predef
ma niejawną konwersję z Int
na Integer
, więc dlaczego jej nie używa? Otrzymuję ten:
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)
Aktualizacja - O przykładu Vinicius
Zamiast próbować tłumaczyć to w komentarzach, tutaj jest wykazanie, że nie istnieje niejawna konwersja miano podczas korzystania typ z kowariantna parametr, taki jak List[+T]
. Powiedzmy, że mogę umieścić ten kod w pliku, skompilować i uruchomić go ...
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")
}
Zobaczysz, że nazywa test, ale nigdy nie jest niejawna konwersja z String
„abc” do Foo
. Zamiast tego wybiera T
dla test[T]
, która jest wspólną podstawową klasą między String
i Foo
. Podczas korzystania z Int
i Integer
wybiera ona Any
, ale jest to mylące, ponieważ reprezentacja środowiska wykonawczego Int
na liście to Integer
. Wygląda więc na to, że użył niejawnej konwersji, ale tak się nie stało. Można sprawdzić, otwierając wiersz Scala ...
scala> :type StackOver1.test(List(new java.lang.Integer(1)), 2)
List[Any]
Okay, dzięki. Rozumiem różnicę wariancji między List i ArrayList, ale niestety dodanie [Integer] nie jest dobre w tym przypadku. To by się stało zbyt wiele i sprawiłoby, że kod byłby brzydki. Chciałbym wiedzieć, dlaczego nie jest używany niejawny. –
Przyjmuję tę odpowiedź, jeśli znajdę coś w dokumentacji lub specyfikacji językowej, która mówi, dlaczego nie bierze pod uwagę tego, co ukryte. Być może wszystkie parametry typu są ustalane przed uwzględnieniem implikacji. Gdyby tak nie było, mógłby użyć 'ArrayList [Integer]' zamiast 'ArrayList [Any]'. Twój przykład nie jest całkiem poprawny ... nie "wymusza niejawnej konwersji". W tym przypadku jest to mylące, ponieważ scala używa 'Integer' w czasie wykonywania dla' Int', ale twoja funkcja testowa otrzymuje po prostu 'List [Any]'. Nie jest wywoływana żadna niejawna funkcja konwersji. –
@RobN, pomóż mi poprawić odpowiedź. Zobaczmy, czy mogę to wyjaśnić. Pierwszy przykład powtarza Twój błąd. Kompilator nie wie, jak dopasować (javageneric, Int) do (javageneric, T). Drugi w Scali pokazuje niejawną konwersję, zauważ, że b jest konwertowane na java.lang.Integer. Nie wiem, gdzie to jest w dokumentacji, po prostu pokazałem ci, eksperymentując. Jeśli masz przykład, który może mi pomóc, proszę. –