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

如何声明重抛函数?附布尔数组扩展抛错函数实现代码

如何将Swift函数声明为重抛函数?

看起来你想把自己实现的indexOfFirstTrue()改成重抛(rethrows)函数,不过得先理清Swift中rethrows的核心逻辑——重抛函数并不是“自己抛出错误”的函数,而是只会传递闭包参数抛出的错误的函数。我来一步步给你讲清楚怎么处理:

先搞懂rethrows的适用场景

rethrows关键字只能用在满足以下条件的函数上:

  • 函数至少接受一个可能抛出错误的闭包参数
  • 函数本身不会主动抛出自定义错误,只会把闭包参数抛出的错误“重新抛出”
  • 如果传入的闭包没有抛出错误,整个函数也不会抛出错误

你的现有函数是主动抛出CustomError的,而且没有闭包参数,所以直接把throws改成rethrows会触发编译器报错——不符合重抛函数的定义。

两种实现重抛逻辑的思路

思路1:调整函数设计,让它依赖闭包参数(符合标准库重抛函数的风格)

如果想让你的数组扩展函数成为重抛函数,可以把判断逻辑改成接受一个闭包参数,让闭包负责抛出错误,函数本身只传递这个错误。比如模仿标准库的index(where:):

enum CustomError: Error {
    case empty
    case doesNotContainMatch
}

extension Array where Element == Bool {
    // 接受一个可能抛出错误的闭包,函数标记为rethrows
    func indexOfFirst(matching predicate: (Element) throws -> Bool) rethrows -> Int {
        guard !isEmpty else {
            // 注意:如果用rethrows,这里不能主动抛出自己的错误!
            // 要把这类错误的抛出逻辑放到闭包里,或者改用throws
            fatalError("数组为空,请通过闭包参数处理该场景")
        }
        
        // 这里重抛闭包predicate抛出的错误
        guard let detectedIndex = try index(where: predicate) else {
            // 同样,主动抛出自定义错误会导致rethrows不成立
            fatalError("未找到匹配元素,请通过闭包参数处理该场景")
        }
        return detectedIndex
    }
}

如果一定要保留自定义错误的抛出,那这个函数必须用throws而不是rethrows——因为主动抛出自己的错误的函数不符合重抛函数的定位。

思路2:让调用这个函数的上层函数成为重抛函数

如果你只是需要在某个上下文里使用重抛逻辑,不需要修改indexOfFirstTrue()本身,可以把调用它的函数声明为rethrows。比如:

// 你的原函数保持不变(还是throws)
enum CustomError: Error {
    case empty
    case doesNotContainTrue
}

extension Array where Element == Bool {
    func indexOfFirstTrue() throws -> Int {
        if isEmpty {
            throw CustomError.empty
        }
        guard let detectedIndex = index(of: true) else {
            throw CustomError.doesNotContainTrue
        }
        return detectedIndex
    }
}

// 上层函数声明为rethrows,它接受一个抛出错误的闭包
func handleArray(_ array: [Bool], with operation: ([Bool]) throws -> Int) rethrows -> Int {
    return try operation(array)
}

// 调用示例
let myArray = [false, true, false, true]
do {
    let firstTrueIndex = try handleArray(myArray) { $0.indexOfFirstTrue() }
    print(firstTrueIndex) // 输出1
} catch CustomError.empty {
    print("数组是空的")
} catch CustomError.doesNotContainTrue {
    print("数组里没有true")
} catch {
    print("其他错误:\(error)")
}

这里handleArray是重抛函数,它本身不抛出错误,只是传递闭包(调用indexOfFirstTrue())抛出的错误。

总结

  • 如果你的函数需要主动抛出自己的错误,它必须是throws函数,不能用rethrows
  • 只有当函数的错误来源是闭包参数,且函数本身不主动抛错时,才能用rethrows
  • 如果你只是需要在某个流程中使用重抛逻辑,可以让调用该函数的上层函数成为重抛函数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:07:22