pub mod bigint;
-pub mod vec_min;
+pub mod vec;
// As our first piece of Rust code, we want to write a function that computes the
// minimum of a list.
-// We are going to make use of the standard library, so let's import that:
-use std;
-
// ## Getting started
// Let us start by thinking about the *type* of our function. Rust forces us to give the types of
// all arguments, and the return type, before we even start writing the body. In the case of our minimum
NumberOrNothing::Nothing => {
min = NumberOrNothing::Number(el);
},
- // In this arm, `min` is currently the number `n`, so let's compute the new minimum and store it.
+ // In this arm, `min` is currently the number `n`, so let's compute the new minimum and store it. We will write
+ // the function `min_i32` just after we completed this one.
NumberOrNothing::Number(n) => {
- let new_min = std::cmp::min(n, el);
+ let new_min = min_i32(n, el);
min = NumberOrNothing::Number(new_min);
}
}
return min;
}
+// Now that we reduced the problem to computing the minimum of two integers, let's do that.
+fn min_i32(a: i32, b: i32) -> i32 {
+ if a < b {
+ return a;
+ } else {
+ return b;
+ }
+}
+
// Phew. We wrote our first Rust function! But all this `NumberOrNothing::` is getting kind of
// ugly. Can't we do that nicer?
// 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
}
}
-// With this fresh knowledge, let us now refactor `vec_min`.
+// Let us now refactor `vec_min`.
fn vec_min(v: Vec<i32>) -> NumberOrNothing {
+ // Remember that helper function `min_i32`? Rust allows us to define such helper functions *inside* other
+ // functions. This is just a matter of namespacing, the inner function has no access to the data of the outer
+ // one. Still, being able to nicely group functions can be very useful.
+ fn min_i32(a: i32, b: i32) -> i32 {
+ if a < b { a } else { b }
+ }
+
let mut min = Nothing;
for e in v {
// Notice that all we do here is compute a new value for `min`, and that it will always end
// can express this uniformity.
min = Number(match min {
Nothing => e,
- Number(n) => std::cmp::min(n, e)
+ Number(n) => min_i32(n, e)
});
}
// The `return` keyword exists in Rust, but it is rarely used. Instead, we typically
// Rust-101, Part 02: Generic types, Traits
// ========================================
-use std;
-
// Let us for a moment reconsider the type `NumberOrNothing`. Isn't it a bit annoying that we
// had to hard-code the type `i32` in there? What if tomorrow, we want a `CharOrNothing`, and
// later a `FloatOrNothing`? Certainly we don't want to re-write the type and all its inherent methods.
// To make the function usable with a `Vec<i32>`, we implement the `Minimum` trait for `i32`.
impl Minimum for i32 {
fn min(self, b: Self) -> Self {
- std::cmp::min(self, b)
+ if self < b { self } else { b }
}
}
// If this printed `3`, then you generic `vec_min` is working! So get ready for the next part.
-// **Exercise 02.2**: Change your program such that it computes the minimum ofa `Vec<f32>` (where `f32` is the type
+// **Exercise 02.2**: Change your program such that it computes the minimum of a `Vec<f32>` (where `f32` is the type
// of 32-bit floating-point numbers). You should not change `vec_min` in any way, obviously!
// [index](main.html) | [previous](part01.html) | [next](part03.html)
// I/O is a complicated topic, so the code to do that is not exactly pretty - but well,
// let's get that behind us.
-// I/O is provided by the module `std::io`, so we first import that.
+// I/O is provided by the module `std::io`, so we first have import that with `use`.
// We also import the I/O *prelude*, which brings a bunch of commonly used I/O stuff
// directly available.
use std::io::prelude::*;
// Rust-101, Part 04: Ownership, Borrowing
// =======================================
-use std::cmp;
-
// Rust aims to be a "safe systems language". As a systems language, of course it
// provides *references* (or *pointers*). But as a safe language, it has to
// prevent bugs like this C++ snippet.
// I also took the liberty to convert the function from `SomethingOrNothing` to the standard
// library type `Option`.
fn vec_min(v: &Vec<i32>) -> Option<i32> {
+ use std::cmp;
+
let mut min = None;
for e in v {
// In the loop, `e` now has type `&i32`, so we have to dereference it to obtain an `i32`.