I understand why this produces a compiler error:
let initialProducer = SignalProducer<Int, NoError>(value:42)
let sideEffectProducer = initialProducer.on(next: { (answer: Int) in
return _
})
The error is
Cannot convert value of type '(Int) -> _' to expected argument type '(Int -> ())?'
So the next parameter takes a closure with an Int parameter that returns Void whilst we're returning _
But why does this compile fine:
let initialProducer = SignalProducer<Int, NoError>(value:42)
let sideEffectProducer = initialProducer.on(next: { (answer: Int) in
return ""
})
we're returning a String, not Void so why does the compiler not complain?
_isn't nothing. It is a pattern, or a part of a pattern that can match anything. It can also be used in an assignment statement to show that you don't care about the result.In your closure, if you want to return nothing, then either:
or omit the return altogether if you're at the end of the closure.
If you return
_, Swift cannot figure out the signature of your closure. You can demonstrate that by doing:If you remove the
_, it compiles fine sincebarbecomes a() -> ().Swift could have given you a better error message like it does if you try to return
_from a function:So, why does
return ""work? Here's a clue.There are some apparent oddness around single-line closures. Consider the following example which is similar to yours:
Running this produces the output:
So, like your example
doitis expecting a(Int) -> ()closure, but we're passing a(Int) -> Stringclosure. And it works...But, if you un-comment the
print(answer + 1)line, thereturn ""then results in the error: