return
return ends the function it is in and hands a value back to the caller.
return-statement = "return" [expression] ";"
func Sign(n: int32) -> int32 {
if n < 0 {
return -1;
}
match n {
0 => return 0,
else => return 1
}
}
With and without a value
A function with a return type returns a value of that type; one without a return type returns with a bare return;, or simply by reaching the end of its body:
func Log(message: char8[..]) {
if message.length == 0 {
return;
}
PrintLine("{}", message);
}
| Mistake | Error |
|---|---|
| a value of the wrong type | 'return' value must have type 'int', but found 'char8[..]' |
| a value from a function with no return type | 'return' cannot have a value in a function with no return type |
| no value from a function with a return type | 'return' requires a value of type 'int' |
The value takes its type from the function the way an annotated binding does: an unsuffixed literal takes the return type, and a narrower integer widens to it.
In a fallible function, return value; is the success and fail error; the failure.
Every path returns
A function with a return type must return on every path through its body. The compiler follows each branch, and one that can reach the closing brace is an error:
func Positive(x: int) -> int {
if x > 0 {
return 1;
}
}
error: function 'Positive' must return a value of type 'int' on every control-flow path
A path that cannot continue counts as finished: a match whose every arm returns, a loop with no break, a call to Panic or to any function marked #NoReturn():
func Day(n: uint) -> char8[..] {
if n < 7 {
return "weekday";
}
Panic("no such day");
}
Returning a move-only value
return name; copies name into the result, like any other use by value. A type that cannot be copied is handed out with <-:
func Pass(token: Token) -> Token {
return <- token;
}
Without the <-:
error: move-only value 'token' requires an explicit '<-' in return
note: plain by-value use copies its source, but 'Token' prohibits copying
help: prefix the return value with '<-', as in 'return <-token'
A freshly made value, such as a structure literal or the result of a call, needs no <-. See Copy and move.
return and defer
return value; evaluates value exactly once, then runs the function's deferred statements, newest first, and only then leaves. Changes a deferred statement makes to a local after that point do not alter the value already captured. See defer.
Inside expressions
return, with or without a value, may also stand where an expression would leave rather than produce one: as a whole match arm, as the fallback of ??, or in an error mapping:
func First(values: int32[..]) -> int32 {
let found: int32? = values.length > 0 ? .Some(values[0]) : none;
let v = found ?? return -1;
return v;
}
Anywhere else it is error: 'return' cannot be used as a value here.