#Result Enum
33 messages · Page 1 of 1 (latest)
but you return something else
you can change it to fn main() -> Result<(), ???>
Main can return anything you see here: https://doc.rust-lang.org/nightly/std/process/trait.Termination.html
A trait for implementing arbitrary return types in the main function.
Yes to both
you assign the value of return Err(e) to y, and you return Err(e)
return Err(e) evaluates to !, which can coerce to any type, i32 in this case
This is also why you can write ```rust
fn main() -> Result<(), DivisionError> {
let y = match divide(4, 2) {
Ok(val) => val,
Err(e) => return return return Err(e),
};
Ok(())
}```
that function does not have the correct return type
right
for the purposes of type inference, and return types, main is just another normal function
i'm not sure i'd say there is an order
the key to understanding how this works is to understand that statements evaluate to values
for example, say you have rust let a: i32 = if x { 42_i32 } else { "foo" }; this does not work because both branches must return something of the type i32
Amethyst 
but both branches must return the same type
the same is true if you write ```rust
let a: i32 = if x {
42_i32
} else {
return y;
};
both branches evaluate to the type i32
the type of a statement is whatever type it evaluates to
with return, it is ! (minus some niche cases where type inference is weird and it evaluates to ())
?play ```rust
#![feature(never_type)]
fn main(){
let x: ! = return;
}```
And continue is the same:
?play ```rust
use std::io::Write;
use std::net::TcpStream;
fn main(){
for x in 0..42{
let stream : TcpStream = continue;
stream.write(&[42]).unwrap();
}
}```
Once you internalize that statements evaluate to values, it is intuitive that this works
(although the last example would be pretty unusual to see)
this is why you can write rust fn foo() -> i32{ 42 } instead of rust fn foo() -> i32{ return 42; }, because the function body is a statement and it evaluates to i32
Never type is weird. I guess the idea is that a value of type ! will never exist, so it's safe to treat it as other types (like i32) because by definition it can never be used. That's nice for certain things like the match case. Hopefully the continue shows up as an unreachable code warning though.
For example here, x will never have a value because we return before it can. It isn't () - that's the empty type, and just means there's no data there. Never means that it can never exist.