TL ; DR:
Rust has no exceptions. A function that can fail returns a Result: Ok with the value, or Err with the error. The caller handles both with match.
fn spend(&mut self, amount: i32) -> Result<i32, String> {
if amount > self.money {
return Err(String::from("not enough money"));
}
self.money -= amount;
Ok(self.money)
}
match wallet.spend(80) {
Ok(left) => println!("{} left", left),
Err(message) => println!("error: {}", message),
}
Full lesson:
Some requests can't be done. A wallet with 50 can't spend 80.
The method could return a special value, like -1. But the caller may forget to check it. Then the program goes on with a wrong number.
Many languages throw an exception here. Rust doesn't. Its result type says that the call can fail.
Returning a Result
Result<i32, String>is one of two things.Ok(v)holds the valuev, ani32here.Err(e)holds the errore, aStringhere.return Err(...)stops the method. So the wallet keeps its money.- The last line,
Ok(self.money), is the result when all went well.
Handling it
- A
matchon the result has one arm for each case. Ok(left)unpacks the value intoleft.Err(message)unpacks the error intomessage.- The compiler wants both arms. So an error can't be forgotten.
It works like Option, which you met before. Ok and Err take the place of Some and None.
Your task
A Wallet starts with 50. Its spend method takes money out and returns what is left.
- In
spend, return anErrwhenamountis more thanself.money. Its message is"not enough money". - In the loop,
matchthe result ofspend. - On
Ok(left), print what was spent and what is left. OnErr(message), printerror:and the message.
The loop tries to spend 20, then 40, then 30.
Expected output:
spent 20, 30 left
error: not enough money
spent 30, 0 leftFree plan: 30 tutor messages. Premium is unlimited.
