What does a func with return type Never do?
For example:
func addNums() -> Nev
Never return type was introduced in Swift 3 to substitute @noreturn key.
See justification in this proposal:
SE-0102 Remove @noreturn attribute and introduce an empty Never type
As official documentation explains:
The return type of functions that do not return normally; a type with no values.
Use Never as the return type when declaring a closure, function, or method that unconditionally throws an error, traps, or otherwise does not terminate.
Source: https://developer.apple.com/documentation/swift/never
Basic illustration:
// The following function is our custom function we would use
// to manually and purposefully trigger crash. In the logs,
// we can specify what exactly went wrong: e.g. couldn't cast something,
// couldn't call something or some value doesn't exist:
func crashApp() -> Never {
fatalError("Something very, very bad happened! Crash the app!")
}
Usage specifics and advantages over @noreturn, as referenced by Erica Sadun:
First note (regarding secondary error remediation) is probably particularly important. Never function can have complex logic and throw – not necessarily crash.
Let's see some interesting use cases and comparison between Never and Void
Example 1
func noReturn() -> Never {
fatalError() // fatalError also returns Never, so no need to `return`
}
func pickPositiveNumber(below limit: Int) -> Int {
guard limit >= 1 else {
noReturn()
// No need to exit guarded scope after noReturn
}
return rand(limit)
}
Example 2
func foo() {
abort()
print("Should not reach here") // Warning for this line
}
Example 3
func bar() -> Int {
if true {
abort() // No warning and no compiler error, because abort() terminates it.
} else {
return 1
}
}
abort() is defined as:
public func abort() -> Never
These examples would not have been possible with it returning Void:
public func abortVoid() -> Void {
fatalError()
}
func bar() -> Int {
if true {
abortVoid() // ERROR: Missing return in a function expected to return 'Int'
} else {
return 1
}
}
And to pack it up with abort() returning Never:
func bar() -> Int {
if true {
abort() // No ERROR, but compiler sees it returns Never and warns:
return 2 // Will never be executed
} else {
return 1
}
}
We use Void to tell compiler there is no return value. Application keeps running.
We use Never to tell compiler there is no return to caller site. Application runloop is terminated.