Как объявить функцию отбрасывания?

Я реализовал следующую функцию - как расширение массива логических значений - которая может выдать 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 в качестве перерабатывающей функции:

Функция или метод могут быть объявлены с ключевым словом rethrows, чтобы указать, что он выдает ошибку, только если один из его параметров функции выдает ошибку. Эти функции и методы известны как функции отбрасывания и методы отбрасывания. Функции и методы возврата должны иметь хотя бы один параметр функции выброса.

Язык программирования Swift (Swift 4.1): Объявления - функции и методы восстановления.

Так что я могу назвать его формулой без броска, поэтому она не выдаст ошибку:

handleResult(myArray.indexOfFirstTrue()) // 2

Но я застрял в том, что я должен отредактировать, чтобы это была функция отбрасывания, поэтому я попытался объявить это как:

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

и я получил ошибку:

ошибка: функция 'rethrows' должна принимать аргумент функции throwing

поэтому я также попытался объявить это как:

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

и, очевидно, получил ошибку:

ошибка: невозможно преобразовать значение типа 'Int' в ожидаемый тип аргумента '() throws -> Int'

Что мне делать на этом этапе?

1 ответ

Решение

Помните, аргумент имеет тип () -> Int! Поэтому вам нужно вызвать переданную функцию, чтобы получить результат! Вам также нужно try Так как функция может бросить.

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

Теперь вы можете использовать это так:

let myArray = [true]
try handleResult(myArray.indexOfFirstTrue)
Другие вопросы по тегам