Control Flow and Error Handling
Expressions
Blocks have value
Operator precedence table is page 141-142 of text. 18 levels. Left associativity. Left-to-right evaluation?
Conversion is mostly explicit through
as
. Only conversions that are safe workReference magic happens
- Auto dereference in certain situations as discussed earlier
- Auto reference conversions in certain situations, e.g.
String
,Vec
,Box
Expressions and Control Flow
In Rust, some of what we would normally do with control flow is done with simple expressions. This is part of Rust's functional-language heritage
if
is an expression type- "method" chaining is a standard mechanism
"Method" Chaining
Many Rust operations are used in an "object-oriented style":
"hello".to_uppercase()
vs
to_uppercase("hello")
This allows stringing together expressions in more readable syntax (and also facilitates proper borrowing/sharing).
https://play.rust-lang.org/?gist=fe8f51647a4cd3268c74e2276bef9089&version=undefined
Explicit Control Flow
if
-else
match
while
if let
,while let
for
and iterators
Error Handling: Panic
panic!
is that thing that should never happen in a proper programPanic is a true exception: will be "unwound" by default, can be caught (!) but normally shouldn't be
Why unwinding? Because drops do cleanup by default, so leave the world safe as possible before exiting
Error Handling: Abort
Can call
std::process::abort()
for non-unwinding immediate stop that will cause a core dump (if enabled)Can debug the result with
gdb
Useful for weird debugging situations
Error Handling: Result
Result
is simple enum type with two value-carrying options:Ok
andErr
"Normal" way to handle errors returned by standard library
Err
takes a value implementingstd::error::Error
; there are many kinds of these in the standard libraryYou can add your own error type
Manually https://raw.githubusercontent.com/pdx-cs-rust/rust-misc/master/parsepoint.rs
Via the
error_chain
crate: gives ability to nest errors reasonablyVia the
failure
crate: fancy derivation, more "modern"
Error Handling: Option
The
Option
type is often used for returning certain kinds of errorStyle question here: best practice is probably to use
Option
for situations where nothing has really "failed" per se, but the semantics get mooted a lot
An Example: Pop On Empty Stack
Could
abort()
: pretty drasticCould
panic!()
: still pretty drastic, but at least proportionateCould return a
Result
with a custom error indicating popping an empty stack. Probably right if intent is forpop()
to be a "partial function"Could return an
Option
. This effectively indicates that popping an empty stack is not to be regarded as an error. Probably right if intent is forpop()
to be a total function