You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin使用泛型时如何防止隐式向上转型为Any的类型转换?

解决方案

方案1:双泛型约束(推荐,无兼容性风险)

直接修改函数定义,拆分泛型约束,让编译器优先识别接收者的元素类型:

fun <T, R : T> Iterable<T>.find2(elem: R) = this.find { it == elem }

原理说明

原来的单泛型写法中,编译器会同时参考接收者类型和参数类型,推导两者的最小公共超类型作为泛型实参,Int和String的公共超类型为Any,因此调用不会报错。
拆分泛型后,T的类型完全由接收者Iterable<T>的实际元素类型决定,参数的类型R被约束为必须是T的子类型,编译器会先确定T的类型再校验参数类型是否符合要求,不会主动向上推导公共超类型规避类型校验。

效果验证

  • 合法调用正常编译:listOf(1, 2, 3).find2(2)
  • 非法调用直接触发编译错误:listOf(1, 2, 3).find2("foo") 会提示类型不匹配,String不属于Int的子类型

方案2:使用@InputTypes注解

如果你不想拆分泛型,可以使用Kotlin内部提供的@InputTypes注解,直接标记泛型优先从接收端推导:

import kotlin.internal.InputTypes

fun <@InputTypes T> Iterable<T>.find2(elem: T) = this.find { it == elem }

注意事项

该注解属于Kotlin内部API,标准库中contains等函数均使用该注解实现同类类型校验,但不排除后续版本调整的可能,兼容性略低于方案1。

内容的提问来源于stack exchange,提问作者Aleksandar Stefanović

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:54:03