I expected the below code to be failed to compile at the last line. because it missed some type expression for type inference.
test.kts
:
import kotlin.reflect.KClass
sealed class Test {
object A : Test()
object B : Test()
companion object {
fun <T : Test> getByClass(c: KClass<T>): T =
@Suppress("UNCHECKED_CAST")
when (c) {
A::class -> A as T
B::class -> B as T
else -> throw IllegalArgumentException("Unexpected class: $c")
}
inline fun <reified T : Test> get(): T = getByClass(T::class)
}
}
fun f1(a: Test.A) {
println(a::class)
}
fun f2(a: Any) {
println(a::class)
}
// Works right
f1(Test.get())
// Just invocation get raises compile error
// Test.get()
// Providing type raises compile error
// Test.get<Any>()
// f2(Test.get<Any>())
// This does not throw compile error
f2(Test.get())
Outputs and versions in my terminal:
$ kotlinc -version
info: kotlinc-jvm 1.4.21 (JRE 11.0.5+10)
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.intellij.util.ReflectionUtil to method java.util.ResourceBundle.setParent(java.util.ResourceBundle)
WARNING: Please consider reporting this to the maintainers of com.intellij.util.ReflectionUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
$ kotlinc -script test.kts
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.intellij.util.ReflectionUtil to method java.util.ResourceBundle.setParent(java.util.ResourceBundle)
WARNING: Please consider reporting this to the maintainers of com.intellij.util.ReflectionUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
class Test$Test$A
java.lang.IllegalArgumentException: Unexpected class: class Test$Test
at Test$Test$Companion.getByClass(test.kts:13)
at Test.<init>(test.kts:32)
This script raises java.lang.IllegalArgumentException: Unexpected class: class Test$Test
at 13th line in getByClass
. The get()
seems to get Test
class as a reified class.
How I should write get()
as type safe? I want the code to be failed at compile, not at runtime.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…