'How to capture type using builder inference in kotlin
Using the new Builder Inference feature in Kotlin allows for the type of a builder to be realised by use, rather than a more explicit declaration.
For instance
class Test<T> {
fun add(a: T) {}
fun secondFun(a: T) {}
fun <T> Test<T>.lambda(a: (T) -> Unit) {}
}
@OptIn(ExperimentalTypeInference::class)
fun <T> builder(@BuilderInference x: Test<T>.() -> Unit): Test<T> {
return Test<T>().apply(x)
}
The following code results in a builder with an Int type as T.
val x = builder {
add(1)
} // has type Test<Int>
Yet, use of the type in further calls after the initial add leads to ambiguity by the kotlin compiler.
val x: Test<Int> = builder {
add(1)
lambda { it + 1 }
}
This fails on the use of the + with
Overload resolution ambiguity:
public operator fun <T> Array<TypeVariable(T)>.plus(element: TypeVariable(T)): Array<TypeVariable(T)> defined in kotlin.collections
public operator fun ByteArray.plus(element: Byte): ByteArray defined in kotlin.collections
public operator fun IntArray.plus(element: Int): IntArray defined in kotlin.collections
public operator fun LongArray.plus(element: Long): LongArray defined in kotlin.collections
public operator fun ShortArray.plus(element: Short): ShortArray defined in kotlin.collections
public operator fun String?.plus(other: Any?): String defined in kotlin
public inline operator fun UByteArray.plus(element: UByte): UByteArray defined in kotlin.collections
public inline operator fun UIntArray.plus(element: UInt): UIntArray defined in kotlin.collections
public inline operator fun ULongArray.plus(element: ULong): ULongArray defined in kotlin.collections
public inline operator fun UShortArray.plus(element: UShort): UShortArray defined in kotlin.collections
public operator fun <T> Collection<TypeVariable(T)>.plus(element: TypeVariable(T)): List<TypeVariable(T)> defined in kotlin.collections
public operator fun <T> Iterable<TypeVariable(T)>.plus(element: TypeVariable(T)): List<TypeVariable(T)> defined in kotlin.collections
public operator fun <T> Set<TypeVariable(T)>.plus(element: TypeVariable(T)): Set<TypeVariable(T)> defined in kotlin.collections
public operator fun <T> Sequence<TypeVariable(T)>.plus(element: TypeVariable(T)): Sequence<TypeVariable(T)> defined in kotlin.sequences
Seemingly, it's not continuing with the idea that the type T is an int. Though IntelliJ does have the Int type hint in its own analysis for it within the lambda.
Is there a way to call the lambda DSL method with it resolving to Int without explicit typing required given that there's already been a call that can infer a type? Or is this a limitation of Builder Inference in kotlin as it's potentially looking for a more specific/general type in future uses of T.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
