为何不符合泛型约束的Kotlin代码可正常编译?
为什么这段Kotlin代码能正常编译?
先来看你提供的代码:
fun main() { print(test(1, "abc", 4)) } fun <T> test(criteria: T, actual: T, points: Int): Int { if (criteria == null) return 0 return if (criteria == actual) points else 0 } // 输出0
你的疑惑完全合理——看起来test函数要求前两个参数是同一泛型类型T,但你传入了Int类型的1和String类型的"abc",却没有编译错误,这是怎么回事?
核心原因在于Kotlin的泛型推断逻辑:编译器会自动为泛型类型T推断出所有相关参数的最具体的共同父类型。在这个例子里,Int和String的共同父类型是Any?(Kotlin里所有类型的顶层父类型,涵盖可空与非空类型)。
换句话说,编译器会把test函数的泛型T解析为Any?,此时函数的实际签名相当于:
fun test(criteria: Any?, actual: Any?, points: Int): Int { // 函数体不变 }
这样一来,1(属于Any?)和"abc"(也属于Any?)就完全符合参数类型要求了,自然能顺利通过编译。而运行时1 == "abc"的结果是false,所以函数返回0,和你看到的输出一致。
如果想要强制要求两个参数必须是完全相同的具体类型(而不是共同父类型),你可以借助reified泛型和类型检查来实现,比如:
inline fun <reified T> test(criteria: T, actual: Any, points: Int): Int { if (criteria == null || actual !is T) return 0 return if (criteria == actual) points else 0 }
这时候再传入1和"abc",编译器就会报错,因为"abc"不是Int类型。
内容的提问来源于stack exchange,提问作者Sarp Başaraner
相关产品推荐
相关产品推荐

