简体   繁体   中英

Understanding a basic Swift compiler error

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.

_ = foo()  // Ignore result returned from foo

In your closure, if you want to return nothing , then either:

return

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:

let bar = { return _ }  // Unable to infer closure return type in current context

If you remove the _ , it compiles fine since bar becomes a () -> () .

Swift could have given you a better error message like it does if you try to return _ from a function:

func foo() {
    return _  // '_' can only appear in a pattern or on the left side of an assignment
}

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:

func doit(handler: (Int) -> ()) {
    handler(17)
    print("doit is done")
}

doit() { (answer: Int) in
    //print(answer + 1)
    return ""
}

Running this produces the output:

doit is done

So, like your example doit is expecting a (Int) -> () closure, but we're passing a (Int) -> String closure. And it works...

But, if you un-comment the print(answer + 1) line, the return "" then results in the error:

Unexpected non-void return in void function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM