twisterrob
07/26/2019, 6:22 PMfun <E> Collection<E>.myContains(item: E) : Boolean
usage: val isItInside: Boolean = listOf(1, 2).myContains("1")
expectation: usage fails to compile, because it's a List<Int>
vs. a String
https://stackoverflow.com/q/57224118/253468Shawn
07/26/2019, 6:27 PME
gets inferred to be Int, so passing in a String is necessarily a compile-time errorBob Glamm
07/26/2019, 6:29 PMtwisterrob
07/26/2019, 6:30 PMBob Glamm
07/26/2019, 6:31 PMinterface Container<E> {
fun contains(item: E): Boolean
}
fun <X> Container<X>.myContains(item: X): Boolean = contains(item)
fun bar() {
val q = object: Container<Int> {
override fun contains(item: Int): Boolean {
return item == 4
}
}
q.myContains("1")
}
radimir.sorokin
07/26/2019, 6:32 PMlistOf<Int>(1, 2)
Bob Glamm
07/26/2019, 6:33 PMfun <E> Collection<E>.myContains(item: E): Boolean = contains(item)
fun <E> itContains(coll: Collection<E>, item: E): Boolean = coll.contains(item)
fun foo() {
val q: List<Int> = listOf(1, 2, 3)
q.myContains("1")
itContains(q, "1")
}
radimir.sorokin
07/26/2019, 6:34 PMtwisterrob
07/26/2019, 6:35 PMfun <E, T : Collection<E>> Asserter<T>.contain(item: E)
, even though I control the variance of class Asserter<T>
, the upper bound of T
is still a covariant Collection
?Bob Glamm
07/26/2019, 6:36 PMtwisterrob
07/26/2019, 6:39 PMBob Glamm
07/26/2019, 6:40 PMkotlin.Collection
and noticed the variance annotationtwisterrob
07/26/2019, 6:42 PMBob Glamm
07/26/2019, 6:46 PMkarelpeeters
07/26/2019, 7:19 PMkotlin.collections.contains
uses an internal annotation for this: @kotlin.internal.OnlyInputTypes
.twisterrob
07/26/2019, 7:27 PMkarelpeeters
07/26/2019, 7:28 PMfun <E> Collection<E>.myContains(item: E)
= item in this
twisterrob
07/26/2019, 7:28 PMkarelpeeters
07/26/2019, 7:28 PMtwisterrob
07/26/2019, 7:29 PMkarelpeeters
07/26/2019, 7:29 PMtwisterrob
07/26/2019, 7:29 PMinline
karelpeeters
07/26/2019, 7:34 PMCtrl+Alt+N
style.inline
actually every changes the behavior.twisterrob
07/26/2019, 7:35 PMGlen
07/29/2019, 3:44 AMdmitriy.novozhilov
07/31/2019, 9:32 AMfun <T> Collection<T>.myContains(element: T): T = TODO()
interface A
interface B
// interface Collection<out E>
fun foo(x: Collection<A>, b: B) {
x.myContains(b)
}
In call x.myContains(b)
compiler should determines type of type variable T
there is following constraints in this call:
B <: T
Collection<A> <: Collection<T>
for that constraint system exists correct solution: T == Any
it's correct since Collection
has out
variance, it's correct that Collection<A> <: Collection<Any>
If you write similar example but instead Collection
will use type invariant type parameter you will get correct type mismatchtwisterrob
08/13/2019, 11:30 AMdmitriy.novozhilov
08/13/2019, 1:38 PMGlen
08/13/2019, 4:54 PM