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

为什么Kotlin的binarySearch方法中Comparator要用in T而非T?

Kotlin二分查找方法中Comparator的作用解析

先看实现代码:

public fun <T> List<T>.binarySearch(element: T, comparator: Comparator<in T>, fromIndex: Int = 0, toIndex: Int = size): Int {
    rangeCheck(size, fromIndex, toIndex)

    var low = fromIndex
    var high = toIndex - 1

    while (low <= high) {
        val mid = (low + high).ushr(1) // safe from overflows
        val midVal = get(mid)
        val cmp = comparator.compare(midVal, element)

        if (cmp < 0)
            low = mid + 1
        else if (cmp > 0)
            high = mid - 1
        else
            return mid // key found
    }
    return -(low + 1)  // key not found
}

为什么用Comparator而非Comparator?

这里的in是Kotlin的逆变关键字,核心作用是放宽比较器的类型限制。Comparator的compare方法是接收输入参数的逻辑,对于输入型参数,逆变允许我们传入一个能处理T父类的比较器。

举个实际例子:假设T是Dog类(继承自Animal),我们有一个通用的Comparator<Animal>用来比较所有动物的属性(比如体重),这个比较器完全能用来比较Dog。如果方法参数写的是Comparator<T>,这个Comparator<Animal>就无法传入;但用Comparator<in T>就可以,因为Animal是Dog的父类,符合in T的类型要求,这样就能复用更通用的比较器,提升方法的灵活性。

不用in会导致功能无法正常运行吗?

这不是单纯为了可读性,不用in不会让方法本身的查找逻辑失效,但会大幅限制它的使用场景。

比如刚才的场景,当你需要用针对T父类的比较器来查找List<T>中的元素时,没有in的话编译器会直接报错,不允许传入该比较器。但从方法逻辑来看,这个比较器是完全兼容的——因为compare方法只需要接收T类型的参数,而父类比较器的compare方法本来就能接收T(因为T是父类的子类)。所以不用in的话,方法功能本身没问题,但能支持的使用场景会少很多,灵活性大打折扣。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:43:26