如何声明重新抛出函数?

How to declare a rethrowing function?

我实现了以下函数 - 作为布尔数组的扩展 - 它可能会引发 CustomError 错误:

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
    }
}

按预期工作:

let myArray = [false, true, false, true]
try print(myArray.indexOfFirstTrue()) // 1

接下来,我尝试将一个函数声明为:

func handleResult(_ index: Int) throws {
    print(index * 2)
    // ...
}

它应该获取 myArray.indexOfFirstTrue() 的结果并用它做一些事情(为简单起见,我们假设它打印乘以 2 的值):

try handleResult(myArray.indexOfFirstTrue()) // 2

我想做的是声明handleResult重新抛出函数:

A function or method can be declared with the rethrows keyword to indicate that it throws an error only if one of its function parameters throws an error. These functions and methods are known as rethrowing functions and rethrowing methods. Rethrowing functions and methods must have at least one throwing function parameter.

The Swift Programming Language (Swift 4.1): Declarations - Rethrowing Functions and Methods.

所以我可以用非抛出公式调用它,这样它就不会抛出错误:

handleResult(myArray.indexOfFirstTrue()) // 2

但是我不知道我应该编辑什么让它成为一个重新抛出的函数,所以我尝试将它声明为:

func handleResult(_ index: Int) rethrows {
    print(index * 2)
}

我得到以下错误:

error: 'rethrows' function must take a throwing function argument

因此,我也尝试声明为:

func handleResult(_ index: (() throws ->  Int)) rethrows {
    print(index * 2)
}

显然得到了错误:

error: cannot convert value of type 'Int' to expected argument type '() throws -> Int'

此时我该怎么办?

记住,参数的类型是() -> Int!所以需要调用传入的函数才能得到结果!您还需要 try 因为函数可以抛出。

func handleResult(_ index: (() throws ->  Int)) rethrows {
    print(try index() * 2) // see the "()"?
}

现在你可以这样使用了:

let myArray = [true]
try handleResult(myArray.indexOfFirstTrue)