Próbuję zadeklarować argument w języku Swift, który przyjmuje opcjonalne zamknięcie. Zadeklarowana przeze mnie funkcja wygląda następująco:
class Promise {
func then(onFulfilled: ()->(), onReject: ()->()?){
if let callableRjector = onReject {
// do stuff!
}
}
}
But Swift complains that "Bound value in a conditional must be an Optional type" where the "if let" is declared.
swift
optional-parameters
Marcosc
źródło
źródło
Odpowiedzi:
You should enclose the optional closure in parentheses. This will properly scope the
?
operator.func then(onFulfilled: ()->(), onReject: (()->())?){ if let callableRjector = onReject { // do stuff! } }
źródło
()->Int?
means.?
is really just sugar forOptional<T>
, so you could also write ` func then(onFulfilled: ()->(), onReject: Optional<()->()>) { ` then you would not need the extra()
, though IMO the()?
is prettier. Also you can make it even prettier with a typealias liketypealias RejectHandler = () -> ()
func then(onFulfilled: ()->(), onReject: RejectHandler?) {
To make the code even shorter we can use
nil
as default value foronReject
parameter and optional chaining?()
when calling it:func then(onFulfilled: ()->(), onReject: (()->())? = nil) { onReject?() }
This way we can omit
onReject
parameter when we callthen
function.then({ /* on fulfilled */ })
We can also use trailing closure syntax to pass
onReject
parameter intothen
function:then({ /* on fulfilled */ }) { // ... on reject }
Here is a blog post about it.
źródło
Since I assume, that this "optional" closure should simply do nothing, you could use a parameter with an empty closure as default value:
func then(onFulfilled: ()->(), onReject: ()->() = {}){ // now you can call your closures onFulfilled() onReject() }
this function can now be called with or without the
onReject
callbackNo need for Swift's awesome
Optionals?
here!źródło
Maybe it's a cleaner way. Specially when the closure has complicated parameters.
typealias SimpleCallBack = () -> () class Promise { func then(onFulfilled: SimpleCallBack, onReject: SimpleCallBack?){ if let callableRjector = onReject { // do stuff! } } }
źródło