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

如何编写适配所有Collection子类且参数类型正确的泛型函数?

修正Kotlin泛型函数的类型校验问题

原代码的核心问题是泛型推断逻辑宽松:编译器会自动把T推断为所有相关类型的共同父类(比如Int和String的共同父类是Any),导致本该拦截的类型不匹配场景被放行。我们可以通过调整泛型约束、优化集合处理逻辑来解决这个问题:

修正后的代码

inline fun <reified T, C : Collection<T>> C.dropElements(word: T): C {
    return when (this) {
        is MutableSet<*> -> (this.apply { remove(word) }) as C
        is Set<*> -> (this - word) as C
        is MutableList<*> -> (this.apply { removeIf { it == word } }) as C
        is List<*> -> filter { it != word } as C
        else -> throw UnsupportedOperationException("不支持该Collection子类")
    }
}

fun main() {
    val originalList: List<String> = readln().split(" ")
    val originalSet: Set<String> = originalList.toSet()
    val word: String = readln()

    val dropElements1: List<String> = originalList.dropElements(word).also(::println)
    val dropElements2: Set<String> = originalSet.dropElements(word).also(::println)

    // 此处会编译报错(符合预期):类型不匹配,String无法传入元素类型为Int的集合
    // val dropElements3: List<Int> = listOf(1, 2, 3).dropElements(word).also(::println)
}

关键修正细节

  • 收紧泛型约束:把reified T放在泛型参数首位,同时明确C必须是Collection<T>的子类。这样编译器会强制要求传入的word类型和集合元素类型严格一致,无法再推断出宽泛的Any类型,非法类型传入会直接触发编译错误。
  • 补充可变集合支持:原代码只处理了不可变的Set和List,新增MutableSet、MutableList的处理逻辑,避免可变集合类型转换时出现异常。
  • 优化错误提示:将通用Exception替换为语义更准确的UnsupportedOperationException,便于排查问题。

内容的提问来源于stack exchange,提问作者Kaloyan Karaivanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:31:06