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

Swift中如何调用自定义二分搜索函数?C开发者遇调用难题

Swift二分搜索函数调用问题修复

问题核心

作为资深C语言开发者,移植C的二分搜索逻辑到Swift后,编译通过但调用时编译器要求手动给eleCompare传参,无法实现由bsearch自动传入参数的预期,同时代码还存在参数不匹配、类型不安全等隐性问题。

问题分析

  1. 参数名不匹配:bsearch函数定义的第一个参数是arr:[Any],但函数内部却用v访问数组,属于笔误;调用时又用v:传递参数,和定义的参数名arr不对应。
  2. 函数类型不兼容:bsearch要求的比较函数类型是(Any, Double)->Int,但eleCompare的类型是(locArrayele, Double)->Int,且Swift中函数参数标签必须匹配(eleCompare带left:/right:标签,而bsearch的闭包要求无标签)。
  3. 类型不安全:使用[Any]会导致数组元素访问时的类型隐患,应该用泛型实现类型安全的二分搜索。
  4. 语法错误:测试代码的print语句缺少闭合双引号,且未导入CoreLocation框架(CLLocationDegrees依赖该框架)。

修复后的完整代码

1. 泛型版二分搜索函数(类型安全)

// 泛型实现,支持指定元素类型,避免Any带来的类型风险
public func bsearch<T>(v: [T], target: Double, compare: (T, Double) -> Int) -> Int {
    guard v.count > 1 else { return -1 }
    
    var lo = 0
    var hi = v.count - 1
    
    while hi - lo > 1 {
        let mid = (lo + hi) / 2
        let cmpResult = compare(v[mid], target)
        if cmpResult == -1 {
            lo = mid + 1
        } else {
            hi = mid
        }
    }
    
    if compare(v[hi], target) == 0 {
        return hi
    }
    return lo
}

2. 调整后的比较函数(匹配闭包类型)

// 省略参数标签,匹配bsearch要求的闭包参数格式
func eleCompare(_ left: locArrayele, _ right: Double) -> Int {
    if right < left.degrees {
        return -1
    } else if right == left.degrees {
        return 0
    } else {
        return 1
    }
}

3. 修正后的测试代码

import CoreLocation // 必须导入才能使用CLLocationDegrees

class locArrayele {
    public var degrees: CLLocationDegrees
    public var ix: Int
    
    init(degrees: CLLocationDegrees, i: Int) {
        self.degrees = degrees
        self.ix = i
    }
}

public var latArray: [locArrayele] = []
// 示例:添加测试数据
latArray.append(locArrayele(degrees: 30.0, i: 0))
latArray.append(locArrayele(degrees: 34.0, i: 1))
latArray.append(locArrayele(degrees: 36.0, i: 2))
latArray.append(locArrayele(degrees: 40.0, i: 3))

// 正确调用bsearch,参数自动传入比较函数
let ix = bsearch(v: latArray, target: 35.0, compare: eleCompare)
print("当纬度为35时,最接近的索引是 \(ix)")

关键修复点说明

  • 泛型改造:用T替代Any,保证数组元素类型统一,消除类型转换风险。
  • 参数标签统一:比较函数使用下划线_省略参数标签,完全匹配bsearch的闭包参数要求,传递函数时无需额外调整。
  • 参数名一致性:bsearch的参数名和调用时的参数名保持一致(均为v:),解决参数不匹配问题。
  • 语法补全:补全print语句的闭合引号,导入CoreLocation框架以使用CLLocationDegrees。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 10:25:03