+// Rust-101, Part 01: Expressions, Inherent methods
+// ================================================
+
+use std;
+
+// Even though our code from the first part works, we can still learn a
+// lot by making it prettier. To understand how, it is important to
+// understand that Rust is an "expression-based" language. This means that most of the
+// terms you write down are not just *statements* (executing code), but *expressions*
+// (returning a value). This applies even to the body of entire functions!
+
+// For example, consider `sqr`:
+fn sqr(i: i32) -> i32 { i * i }
+// Between the curly braces, we are giving the *expression* that computes the return value.
+// So we can just write `i * i`, the expression that returns the square if `i`!
+// This is very close to how mathematicians write down functions (but with more types).
+
+// Conditionals are also just expressions. You can compare this to the ternary `? :` operator
+// from languages like C.
+fn abs(i: i32) -> i32 { if i >= 0 { i } else { -i } }
+
+// And the same applies to case distinction with `match`: Every `arm` of the match
+// gives the expression that is returned in the respective case.
+// (We repeat the definition from the previous part here.)
+enum NumberOrNothing {
+ Number(i32),
+ Nothing
+}
+use self::NumberOrNothing::{Number,Nothing};
+fn number_or_default(n: NumberOrNothing, default: i32) -> i32 {
+ match n {
+ Nothing => default,
+ Number(n) => n,
+ }
+}
+
+// With this fresh knowledge, let us now refactor `vec_min`. First of all, we are doing a small change
+// to the type: `&Vec<i32>` denotes a *reference* to a `Vec<i32>`. You can think of this as a pointer
+// (in C terms): Arguments in Rust are passed *by value*, so we need to employ explicit references if
+// that's not what we want. References are per default immutable (like variables), a mutable reference
+// would be denoted `&mut Vec<i32>`.
+fn vec_min(v: &Vec<i32>) -> NumberOrNothing {
+ let mut min = Nothing;
+ for e in v {
+ // Now that `v` is just a reference, the same goes for `e`, so we have to dereference the pointer.
+ let e = *e;
+ // Notice that all we do here is compute a new value for `min`, and that it will always end
+ // up being a `Number` rather than `Nothing`. In Rust, the structure of the code
+ // can express this uniformity.
+ min = Number(match min {
+ Nothing => e,
+ Number(n) => std::cmp::min(n, e)
+ });
+ }
+ // The `return` keyword exists in Rust, but it is rarely used. Instead, we typically
+ // make use of the fact that the entire function body is an expression, so we can just
+ // write down the desired return value.
+ min
+}