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

如何判断两个Swift函数是否为同一引用?

Swift中如何比较函数引用是否相同?

问题场景

我定义了一个接收函数作为参数的方法:

mutating func updateAccessCaches(by areInIncreasingOrder: (NumberedFile, NumberedFile) -> Bool = sortByOldIDPrio) { ... }

尝试直接比较传入的函数和默认函数是否为同一引用:

if areInIncreasingOrder == sortByOldIDPrio { ... }

但触发报错:

Binary operator '==' cannot be applied to operands of type '(DSRenamer.NumberedFile, DSRenamer.NumberedFile) -> Swift.Bool' and '(DSRenamer.NumberedFile, DSRenamer.NumberedFile) -> Swift.Bool'

不想通过调用函数比较结果的方式判断,想实现类似C语言中直接对比函数引用的效果。

解决方案

Swift本身不支持直接比较函数类型的相等性——因为函数类型可能包含捕获上下文的闭包,无法简单判断引用是否一致。但针对无上下文捕获的函数(比如顶层函数、类型静态方法),可以用以下两种方式实现:

1. 通过内存地址比较(仅适用于无捕获的函数)

利用unsafeBitCast将函数转换为内存指针,直接对比地址是否相同:

// 将函数转换为原始指针
let defaultFuncPtr = unsafeBitCast(sortByOldIDPrio, to: UnsafeRawPointer.self)
let inputFuncPtr = unsafeBitCast(areInIncreasingOrder, to: UnsafeRawPointer.self)

if defaultFuncPtr == inputFuncPtr {
    // 两个函数是同一引用
}

⚠️ 注意:这种方法绝对不能用在捕获了变量的闭包上,会导致未定义行为,仅适用于无上下文的纯函数。

2. 封装为枚举/自定义类型(安全通用方案)

如果需要更安全的逻辑区分,可以把排序策略封装成枚举,用枚举值代替直接传递函数:

enum SortStrategy {
    // 默认排序策略
    case oldIDPrio
    // 自定义排序闭包
    case custom((NumberedFile, NumberedFile) -> Bool)
    
    // 执行排序比较的方法
    func compare(_ a: NumberedFile, _ b: NumberedFile) -> Bool {
        switch self {
        case .oldIDPrio:
            return sortByOldIDPrio(a, b)
        case .custom(let comparator):
            return comparator(a, b)
        }
    }
}

然后修改原方法的参数类型:

mutating func updateAccessCaches(by strategy: SortStrategy = .oldIDPrio) {
    if strategy == .oldIDPrio {
        // 匹配默认策略的专属逻辑
    }
    // 使用排序策略时调用:strategy.compare(fileA, fileB)
}

这种方式完全规避了函数引用比较的问题,同时逻辑更清晰,也支持自定义排序需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:42:25