Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing throwing functions as arguments

I am trying to simply pass a throwing function as an argument to another function, which will then cope with swift's error handling:

enum Err: ErrorType {
    case pfui
}

func bad(i: Int) throws -> String {
    if i < 10 {
        return String(i)
    } else {
        throw Err.pfui
    }
}

func handle(@autoclosure f: () throws -> String) -> String {
    do {
        return try f()
    }
    catch {
        return "oh snap"
    }
}


// error: call can throw but is not marked with 'try'
handle(bad(3))

It must be something simple that I am missing, but somehow the autoclosure attribute does not keep the compiler from thinking that I am actually calling it.

like image 788
Thorsten Karrer Avatar asked Jan 15 '16 16:01

Thorsten Karrer


People also ask

How to pass function to a function as a parameter Swift?

To pass function as parameter to another function in Swift, declare the parameter to receive a function with specific parameters and return type. The syntax to declare the parameter that can accept a function is same as that of declaring a variable to store a function.

What does throwing a function mean?

A throw() specification on a function declaration indicates which specific exception(s) the function is allowed to throw to the caller. It is a kind of contract so the caller knows what to expect. If no throw() is specified, the function is allowed to throw any exception.

What does throws do Swift?

A throwing function propagates errors that are thrown inside of it to the scope from which it's called. Only throwing functions can propagate errors. Any errors thrown inside a nonthrowing function must be handled inside the function.


1 Answers

You can also use the rethrows keyword on handle to indicate that if the closure is a throwing function, handle will "re-throw" it. If you do that, then you don't need to catch the error inside of handle. So it depends on where you want to catch the error:

func handle(@autoclosure f: () throws -> String) rethrows -> String {
    return try f()
}

do { 
    try handle(bad(11))
} catch {
    print("\(error)")      // prints "pfui"
}

I guess it just depends on where you want to do your error handling. Do you want all errors handled inside of handle, or do you want to be able to handle them outside of handle?

like image 149
Aaron Rasmussen Avatar answered Sep 21 '22 20:09

Aaron Rasmussen