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);
}
MistakeError
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.

See also

  • Functions — return types
  • main — what Main returns to the operating system
  • Errors — fail, the other way out of a fallible function
  • defer — what runs on the way out
  • Learn: Return