// ===================
//
// This is [Rust-101](https://www.ralfj.de/projects/rust-101/), a small tutorial for
-// the [Rust language](http://www.rust-lang.org/). It is intended to be an interactive,
+// the [Rust language](https://www.rust-lang.org/). It is intended to be an interactive,
// hands-on course: I believe the only way to *really* learn a language is to write code
// in it, so you should be coding during the course.
//
// ---------------
//
// You will need to have Rust installed, of course. It is available for download on
-// [the Rust website](http://www.rust-lang.org/). Make sure you get at least version 1.2.
+// [the Rust website](https://www.rust-lang.org/). Make sure you get at least version 1.2.
// More detailed installation instructions are provided in
// [the second chapter of The Book](https://doc.rust-lang.org/stable/book/installing-rust.html).
// This will also install `cargo`, the tool responsible for building rust projects (or *crates*).
//
-// Next, fetch the Rust-101 source code from the [git repository](http://www.ralfj.de/git/rust-101.git)
+// Next, fetch the Rust-101 source code from the [git repository](https://www.ralfj.de/git/rust-101.git)
// (also available [on GitHub](https://github.com/RalfJung/rust-101), and as a
// [zip archive](https://github.com/RalfJung/rust-101/archive/master.zip) in case you don't have git installed).
//
// * [Rust by Example](http://rustbyexample.com/)
// * The [Rust Subreddit](https://www.reddit.com/r/rust/)
// * A [collection of links](https://github.com/ctjhoa/rust-learning) to blog posts, articles, videos, etc. for learning Rust.
-// * For the IRC channel and other forums, see the "Community" section of the [Rust Documentation index](http://doc.rust-lang.org/index.html)
+// * For the IRC channel and other forums, see the "Community" section of the [Rust Documentation index](https://doc.rust-lang.org/index.html)
type NumberOrNothing = SomethingOrNothing<i32>;
//@ However, we can also write `SomethingOrNothing<bool>` or even `SomethingOrNothing<SomethingOrNothing<i32>>`.
//@ In fact, such a type is so useful that it is already present in the standard library: It's called an
-//@ *option type*, written `Option<T>`. Go check out its [documentation](http://doc.rust-lang.org/stable/std/option/index.html)!
+//@ *option type*, written `Option<T>`. Go check out its [documentation](https://doc.rust-lang.org/stable/std/option/index.html)!
//@ (And don't worry, there's indeed lots of material mentioned there that we did not cover yet.)
// ## Generic `impl`, Static functions
//@ for that, but there is a catch: What happens if there is some other piece of code running
//@ concurrently, that also reads from standard input? The result would be a mess. Hence
//@ Rust requires us to `lock` standard input if we want to perform large operations on
- //@ it. (See [the documentation](http://doc.rust-lang.org/stable/std/io/struct.Stdin.html) for more
+ //@ it. (See [the documentation](https://doc.rust-lang.org/stable/std/io/struct.Stdin.html) for more
//@ details.)
for line in stdin.lock().lines() {
// Rust's type for (dynamic, growable) strings is `String`. However, our variable `line`
// here is not yet of that type: It has type `io::Result<String>`.
//@ The problem with I/O is that it can always go wrong. The type of `line` is a lot like `Option<String>` ("a `String` or
//@ nothing"), but in the case of "nothing", there is additional information about the error.
- //@ Again, I recommend to check [the documentation](http://doc.rust-lang.org/stable/std/io/type.Result.html).
+ //@ Again, I recommend to check [the documentation](https://doc.rust-lang.org/stable/std/io/type.Result.html).
//@ You will see that `io::Result` is actually just an alias for `Result`, so click on that to obtain
//@ the list of all constructors and methods of the type.
//@ are used correctly, *while looking only at the function type*. At no point in our analysis of `rust_foo` did
//@ we have to look *into* `head`. That's, of course, crucial if we want to separate library code from application code.
//@ Most of the time, we don't have to explicitly add lifetimes to function types. This is thanks to *lifetimes elision*,
-//@ where Rust will automatically insert lifetimes we did not specify, following some [simple, well-documented rules](http://doc.rust-lang.org/stable/book/lifetimes.html#lifetime-elision).
+//@ where Rust will automatically insert lifetimes we did not specify, following some [simple, well-documented rules](https://doc.rust-lang.org/stable/book/lifetimes.html#lifetime-elision).
//@ [index](main.html) | [previous](part05.html) | [next](part07.html)
//@ Since implementing `PartialEq` is a fairly mechanical business, you can let Rust automate this
//@ by adding the attribute `derive(PartialEq)` to the type definition. In case you wonder about
-//@ the "partial", I suggest you check out the documentation of [`PartialEq`](http://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
-//@ and [`Eq`](http://doc.rust-lang.org/std/cmp/trait.Eq.html). `Eq` can be automatically derived as well.
+//@ the "partial", I suggest you check out the documentation of [`PartialEq`](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
+//@ and [`Eq`](https://doc.rust-lang.org/std/cmp/trait.Eq.html). `Eq` can be automatically derived as well.
// Now we can compare `BigInt`s. Rust treats `PratialEq` special in that it is wired to the operator `==`:
//@ That operator can not be used on our numbers! Speaking in C++ terms, we just overloaded the `==` operator
//@ functions depending on the type of the argument). Instead, one typically finds (or defines) a
//@ trait that catches the core characteristic common to all the overloads, and writes a single
//@ function that's generic in the trait. For example, instead of overloading a function for all
-//@ the ways a string can be represented, one writes a generic functions over [ToString](http://doc.rust-lang.org/std/string/trait.ToString.html).
+//@ the ways a string can be represented, one writes a generic functions over [ToString](https://doc.rust-lang.org/std/string/trait.ToString.html).
//@ Usually, there is a trait like this that fits the purpose - and if there is, this has the great
//@ advantage that any type *you* write, that can convert to a string, just has to implement
//@ that trait to be immediately usable with all the functions out there that generalize over `ToString`.
//@ that users can understand, while `Debug` is meant to show the internal state of data and targeted at
//@ the programmer. The latter is what we want for `assert_eq!`, so let's get started.
-// All formating is handled by [`std::fmt`](http://doc.rust-lang.org/std/fmt/index.html). I won't explain
+// All formating is handled by [`std::fmt`](https://doc.rust-lang.org/std/fmt/index.html). I won't explain
// all the details, and refer you to the documentation instead.
use std::fmt;
//@ The reason for this is that many serious security vulnerabilities have been caused by integer overflows, so just assuming
//@ "per default" that they are intended is dangerous. <br/>
//@ If you explicitly *do* want an overflow to happen, you can call the `wrapping_add`
- //@ function (see [the documentation](http://doc.rust-lang.org/stable/std/primitive.u64.html#method.wrapping_add),
+ //@ function (see [the documentation](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.wrapping_add),
//@ there are similar functions for other arithmetic operations). There are also similar functions
//@ `checked_add` etc. to enforce the overflow check.
let sum = a.wrapping_add(b);
impl ops::Add<BigInt> for BigInt {
//@ Besides static functions and methods, traits can contain *associated types*: This is a type chosen by every particular implementation
//@ of the trait. The methods of the trait can then refer to that type. In the case of addition, it is used to give the type of the result.
- //@ (Also see the [documentation of `Add`](http://doc.rust-lang.org/stable/std/ops/trait.Add.html).)
+ //@ (Also see the [documentation of `Add`](https://doc.rust-lang.org/stable/std/ops/trait.Add.html).)
//@
//@ In general, you can consider the two `BigInt` given above (in the `impl` line) *input* types of trait search: When
//@ `a + b` is invoked with `a` having type `T` and `b` having type `U`, Rust tries to find an implementation of `Add` for
//@ In the following, we will look into the iterator mechanism of Rust and make our `BigInt` compatible
//@ with the `for` loops. Of course, this is all about implementing certain traits again. In particular,
-//@ an iterator is something that implements the `Iterator` trait. As you can see in [the documentation](http://doc.rust-lang.org/stable/std/iter/trait.Iterator.html),
+//@ an iterator is something that implements the `Iterator` trait. As you can see in [the documentation](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html),
//@ this trait mandates a single function `next` returning an `Option<Self::Item>`, where `Item` is an
//@ associated type chosen by the implementation. (There are many more methods provided for `Iterator`,
//@ but they all have default implementations, so we don't have to worry about them right now.)
// ## Iterator conversion trait
//@ If you closely compare the `for` loop in `main` above, with the one in `part06::vec_min`, you will notice that we were able to write
//@ `for e in v` earlier, but now we have to call `iter`. Why is that? Well, the `for` sugar is not actually tied to `Iterator`.
-//@ Instead, it demands an implementation of [`IntoIterator`](http://doc.rust-lang.org/stable/std/iter/trait.IntoIterator.html).
+//@ Instead, it demands an implementation of [`IntoIterator`](https://doc.rust-lang.org/stable/std/iter/trait.IntoIterator.html).
//@ That's a trait of types that provide a *conversion* function into some kind of iterator. These conversion traits are a frequent
//@ pattern in Rust: Rather than demanding that something is an iterator, or a string, or whatever; one demands that something
//@ can be converted to an iterator/string/whatever. This provides convenience similar to overloading of functions: The function
// And as a final example, one can also collect all elements of an iterator, and put them, e.g., in a vector.
fn filter_vec_by_divisor(v: &Vec<i32>, divisor: i32) -> Vec<i32> {
//@ Here, the return type of `collect` is inferred based on the return type of our function. In general, it can return anything implementing
- //@ [`FromIterator`](http://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html). Notice that `iter` gives us an iterator over
+ //@ [`FromIterator`](https://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html). Notice that `iter` gives us an iterator over
//@ borrowed `i32`, but we want to own them for the result, so we insert a `map` to dereference.
v.iter().map(|n| *n).filter(|n| *n % divisor == 0).collect() /*@*/
}
-// **Exercise 10.1**: Look up the [documentation of `Iterator`](http://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) to learn about more functions
+// **Exercise 10.1**: Look up the [documentation of `Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) to learn about more functions
// that can act on iterators. Try using some of them. What about a function that sums the even numbers of an iterator? Or a function that computes the
// product of those numbers that sit at odd positions? A function that checks whether a vector contains a certain number? Whether all numbers are
// smaller than some threshold? Be creative!
//@ a *pointer* to such a type (be it a `Box` or a borrow) will need to complete this information. We say that pointers to
//@ trait objects are *fat*. They store not only the address of the object, but (in the case of trait objects) also a *vtable*: A
//@ table of function pointers, determining the code that's run when a trait method is called. There are some restrictions for traits to be usable
-//@ as trait objects. This is called *object safety* and described in [the documentation](http://doc.rust-lang.org/stable/book/trait-objects.html) and [the reference](http://doc.rust-lang.org/reference.html#trait-objects).
+//@ as trait objects. This is called *object safety* and described in [the documentation](https://doc.rust-lang.org/stable/book/trait-objects.html) and [the reference](https://doc.rust-lang.org/reference.html#trait-objects).
//@ In case of the `FnMut` trait, there's only a single action to be performed: Calling the closure. You can thus think of a pointer to `FnMut` as
//@ a pointer to the code, and a pointer to the environment. This is how Rust recovers the typical encoding of closures as a special case of a more
//@ general concept.
//@ sure that the callbacks do not reference any pointers that might become invalid? This is just as crucial for spawning
//@ a thread: In general, that thread could last for much longer than the current stack frame. Thus, it must not use
//@ any pointers to data in that stack frame. This is achieved by requiring the `FnOnce` closure passed to `thread::spawn`
-//@ to be valid for lifetime `'static`, as you can see in [its documentation](http://doc.rust-lang.org/stable/std/thread/fn.spawn.html).
+//@ to be valid for lifetime `'static`, as you can see in [its documentation](https://doc.rust-lang.org/stable/std/thread/fn.spawn.html).
//@ This avoids another kind of data race, where the thread's access races with the callee deallocating its stack frame.
//@ It is only thanks to the concept of lifetimes that this can be expressed as part of the type of `spawn`.
// ## External Dependencies
//@ This leaves us with just one more piece to complete rgrep: Taking arguments from the command-line. We could now directly work on
-//@ [`std::env::args`](http://doc.rust-lang.org/stable/std/env/fn.args.html) to gain access to those arguments, and this would become
+//@ [`std::env::args`](https://doc.rust-lang.org/stable/std/env/fn.args.html) to gain access to those arguments, and this would become
//@ a pretty boring lesson in string manipulation. Instead, I want to use this opportunity to show how easy it is to benefit from
//@ other people's work in your program.
//@
//@ which we already discussed in a single-threaded context in part 12.
//@
//@ ## `Mutex`
-//@ The most basic type for interior mutability that supports concurrency is [`Mutex<T>`](http://doc.rust-lang.org/stable/std/sync/struct.Mutex.html).
+//@ The most basic type for interior mutability that supports concurrency is [`Mutex<T>`](https://doc.rust-lang.org/stable/std/sync/struct.Mutex.html).
//@ This type implements *critical sections* (or *locks*), but in a data-driven way: One has to specify
//@ the type of the data that's protected by the mutex, and Rust ensures that the data is *only* accessed
//@ through the mutex. In other words, "lock data, not code" is actually enforced by the type system, which
// the data inside the lock. Change the code above to do that. Try using `unwrap_or_else` for this job.
//@ ## `RwLock`
-//@ Besides `Mutex`, there's also [`RwLock`](http://doc.rust-lang.org/stable/std/sync/struct.RwLock.html), which
+//@ Besides `Mutex`, there's also [`RwLock`](https://doc.rust-lang.org/stable/std/sync/struct.RwLock.html), which
//@ provides two ways of locking: One that grants only read-only access, to any number of concurrent readers, and another one
//@ for exclusive write access. Notice that this is the same pattern we already saw with shared vs. mutable borrows. Hence
//@ another way of explaining `RwLock` is to say that it is like `RefCell`, but works even for concurrent access. Rather than
//@
//@ In part 13, we talked about types that are marked `Send` and thus can be moved to another thread. However, we did *not*
//@ talk about the question whether a borrow is `Send`. For `&mut T`, the answer is: It is `Send` whenever `T` is send.
-//@ `&mut` allows moving values back and forth, it is even possible to [`swap`](http://doc.rust-lang.org/stable/std/mem/fn.swap.html)
+//@ `&mut` allows moving values back and forth, it is even possible to [`swap`](https://doc.rust-lang.org/stable/std/mem/fn.swap.html)
//@ the contents of two mutably borrowed values. So in terms of concurrency, sending a mutable borrow is very much like
//@ sending full ownership, in the sense that it can be used to move the object to another thread.
//@
//@ Clearly, that's an unsafe operation and must only be used with great care - or even better, not at all. Seriously.
//@ If at all possible, you should never use `transmute`. <br/>
//@ We are making the assumption here that a `Box` and a raw pointer have the same representation in memory. In the future,
-//@ Rust will [provide](http://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#method.from_raw) such [operations](http://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#method.into_raw) in the standard library, but the exact API is still being fleshed out.
+//@ Rust will [provide](https://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#method.from_raw) such [operations](https://doc.rust-lang.org/beta/alloc/boxed/struct.Box.html#method.into_raw) in the standard library, but the exact API is still being fleshed out.
//@ We declare `raw_into_box` to be an `unsafe` function, telling Rust that calling this function is not generally safe.
//@ This grants us the unsafe powers for the body of the function: We can dereference raw pointers, and - most importantly - we
// ## Formatting
-// All formating is handled by [`std::fmt`](http://doc.rust-lang.org/std/fmt/index.html). I won't explain
+// All formating is handled by [`std::fmt`](https://doc.rust-lang.org/std/fmt/index.html). I won't explain
// all the details, and refer you to the documentation instead.
use std::fmt;
unimplemented!()
}
-// **Exercise 10.1**: Look up the [documentation of `Iterator`](http://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) to learn about more functions
+// **Exercise 10.1**: Look up the [documentation of `Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) to learn about more functions
// that can act on iterators. Try using some of them. What about a function that sums the even numbers of an iterator? Or a function that computes the
// product of those numbers that sit at odd positions? A function that checks whether a vector contains a certain number? Whether all numbers are
// smaller than some threshold? Be creative!