Shouldn't `public operator fun <T> Array<...
# stdlib
m
Shouldn't
public operator fun <T> Array<T>.plus(elements: Array<out T>): Array<T>
have
out
receiver variance?
Copy code
enum class A { A }
enum class B { B }
val sum = A.values() + B.values()

// adding the following function makes the code above work:
private inline operator fun <reified T> Array<out T>.plus(elements: Array<out T>): Array<T> {
    val sum = arrayOfNulls<T>(size + elements.size)
    System.arraycopy(this, 0, sum, 0, size)
    System.arraycopy(elements, 0, sum, size, elements.size)
    return sum as Array<T>
}
d
Can your function be done without
inline
?
m
Nope. It can have smaller body:
Copy code
inline operator fun <reified T> Array<out T>.plus(elements: Array<out T>): Array<T> {
    @Suppress("UNCHECKED_CAST") // make non-nullable
    return copyContents(this, elements, arrayOfNulls<T>(size + elements.size)) as Array<T>
}
    
fun <T> copyContents(src1: Array<out T>, src2: Array<out T>, dest: Array<T>): Array<T> {
    System.arraycopy(src1, 0, dest, 0, src1.size)
    System.arraycopy(src2, 0, dest, src1.size, src2.size)
    return dest
}
i
plus
defined this way (as inline reified) couldn't be used for array with non-reified generic element type.
m
Oh, I see. Why don't Kotlin use
Object[]
under the hood, erasing arrays like generics? Only for interop?
d
Kotlin does.
m
It is ain't true.
Array<X>
will be
X[]
under the hood. That's why array factories (
Array<T>
,
arrayOfNulls
) require reified type parameters.
d
Only if
X
is known at runtime.
But even then,
X
is erased anyways.