sort.Search不能直接用于查找相等元素,因其语义是找第一个满足条件的位置,需先用a[i]>=target定位左边界,再显式验证索引有效性和值匹配。

别用 sort.Search 查“相等”就完事——它返回插入位置,不是命中结果,漏验证必出错。
为什么 sort.Search 不能直接写 a[i] == target
常见错误是把断言函数写成 func(i int) bool { return a[i] == target }。这会导致:
– 目标不存在时,sort.Search 仍会一路扫到 i == len(a),然后在断言里访问 a[i] panic;
– 即使没 panic(比如数组 []int{1,3,5} 查 4),它返回索引 2(因为 a[2] >= 4 成立),但 a[2] == 5 ≠ 4,逻辑已错。
根本原因:sort.Search 的语义是「找第一个满足条件的位置」,不是「找等于 target 的位置」。
正确用法:两步走,先定位再验证
升序切片下,查存在性或首次出现位置,必须:
– 第一步:用 a[i] >= target 找左边界
– 第二步:显式检查索引是否越界、值是否真匹配
示例:
idx := sort.Search(len(a), func(i int) bool { return a[i] >= target })
if idx < len(a) && a[idx] == target {
// 找到了,idx 是首次出现位置
} else {
// 没找到
}空切片安全:sort.Search(0, ...) 返回 0,后续 idx 自动为 <code>false,不会 panic。
立即学习“go语言免费学习笔记(深入)”;
查重复元素的左右边界怎么调
基础版一命中就返,但业务常要「第一个 3」或「最后一个 3」——只需改收缩方向,不改框架:
– 找左边界:命中时执行 right = mid - 1,循环结束后检查 left 是否越界及 a[left] == target
– 找右边界:命中时执行 left = mid + 1,循环结束后检查 right 是否越界及 a[right] == target
注意:找右边界时断言函数应为 a[i] > target,最后返回 right(即 left - 1)。
降序数组或结构体字段查找要注意什么
sort.Search 本身不支持降序,硬套会错:
– 降序数组必须反转比较逻辑,比如把 a[i] >= target 改成 a[i] ,并确保语义一致<br>– 查结构体字段(如 <code>users[i].Age >= 25)时,别用闭包捕获整个切片变量,否则编译器无法内联,性能掉档;直接写字段访问即可
最易被忽略的一点:所有二分都要求输入切片**升序且已排序**。传入无序数据,结果完全不可预测——这不是 bug,是前提失效。


















