(this one is for yoshi-enthusiast):
- ! (pronounced as "never") is a special type, which can never be instantiated. It has an important property of being auto-convertable to any other type. This is useful for language primitives that affect control flow. For example:
Code: Select all
//this function never exits fn panic() -> ! { ... }Code: Select all
let opt = Some(10); let value: i32 = match opt { Some(v) => v, None => panic!("it crashed"); // ! is converted to i32, as in this branch we never return anyway };
I've been wondering for a while what's the reasoning behind rust's parser aggressive "make everything an expression" attitude. There are only f̶o̶u̶r̶ three types of statements: item, macro, let binding and expression with ; at the end.
So why make return, break, etc. expressions? They all evaluate to ! anyway. and furthermore it results in weirdness like
Code: Select all
let x = foo(return 5);
Today it suddenly hit me. (UPD: and as it happens, right after the "discovery" I've stumbled on a HN discussion where the exact same thing is stated multiple times).
I'm sure there are more, but one of the benefits is improved ergonomics of match statements. Code like
Code: Select all
let x = match value {
Some(v) => v,
None => return None,
};
Code: Select all
=> { return None; }
I was doing to ponder on how this could be avoided, but it really isn't a problem in the first place. Having a block clearly indicates the intent to ignore the output of a function, which would otherwise be either lost completely (potentially bad), or needed to be stated in a comment (gross).
Bonus: enjoy this beautiful piece (and a valid rust program), proudly residing at weird_exprs.rs, among other specimen.
Code: Select all
fn zombiejesus() {
loop {
while (return) {
if (return) {
match (return) {
1 => {
if (return) {
return
} else {
return
}
}
_ => { return }
};
} else if (return) {
return;
}
}
if (return) { break; }
}
}
Code: Select all
let x = {
{ return; };
5
};