From: Ralf Jung Date: Tue, 23 Jun 2015 15:27:36 +0000 (+0200) Subject: avoid using std::cmp::min, for it doesn't support f32... X-Git-Url: https://git.ralfj.de/rust-101.git/commitdiff_plain/5e5b934f2df7852e021c6cc3f89e313a08345560?hp=f9bb29fcf0e25966dddd1dca29d70d392a5dfdca avoid using std::cmp::min, for it doesn't support f32... --- diff --git a/solutions/src/lib.rs b/solutions/src/lib.rs index aff442c..cbe9705 100644 --- a/solutions/src/lib.rs +++ b/solutions/src/lib.rs @@ -1,2 +1,2 @@ pub mod bigint; -pub mod vec_min; +pub mod vec; diff --git a/src/part00.rs b/src/part00.rs index 4deb829..1648ba1 100644 --- a/src/part00.rs +++ b/src/part00.rs @@ -4,9 +4,6 @@ // 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 @@ -48,9 +45,10 @@ fn vec_min(vec: Vec) -> NumberOrNothing { 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); } } @@ -59,6 +57,15 @@ fn vec_min(vec: Vec) -> NumberOrNothing { 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? diff --git a/src/part01.rs b/src/part01.rs index 05696a5..bb3e919 100644 --- a/src/part01.rs +++ b/src/part01.rs @@ -1,8 +1,6 @@ // 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 @@ -35,8 +33,15 @@ fn number_or_default(n: NumberOrNothing, default: i32) -> i32 { } } -// With this fresh knowledge, let us now refactor `vec_min`. +// Let us now refactor `vec_min`. fn vec_min(v: Vec) -> 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 @@ -44,7 +49,7 @@ fn vec_min(v: Vec) -> NumberOrNothing { // 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 diff --git a/src/part02.rs b/src/part02.rs index 57dc83e..e4f50be 100644 --- a/src/part02.rs +++ b/src/part02.rs @@ -1,8 +1,6 @@ // 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. @@ -114,7 +112,7 @@ pub fn vec_min(v: Vec) -> SomethingOrNothing { // To make the function usable with a `Vec`, 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 } } } @@ -144,7 +142,7 @@ pub fn main() { // 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` (where `f32` is the type +// **Exercise 02.2**: Change your program such that it computes the minimum of a `Vec` (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) diff --git a/src/part03.rs b/src/part03.rs index fa82eb7..9ab153d 100644 --- a/src/part03.rs +++ b/src/part03.rs @@ -6,7 +6,7 @@ // 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::*; diff --git a/src/part04.rs b/src/part04.rs index 14deb89..663e01e 100644 --- a/src/part04.rs +++ b/src/part04.rs @@ -1,8 +1,6 @@ // 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. @@ -67,6 +65,8 @@ fn ownership_demo() { // I also took the liberty to convert the function from `SomethingOrNothing` to the standard // library type `Option`. fn vec_min(v: &Vec) -> Option { + 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`.