more https
authorRalf Jung <post@ralfj.de>
Sun, 23 Aug 2015 11:15:28 +0000 (13:15 +0200)
committerRalf Jung <post@ralfj.de>
Sun, 23 Aug 2015 11:15:28 +0000 (13:15 +0200)
15 files changed:
src/main.rs
src/part02.rs
src/part03.rs
src/part06.rs
src/part07.rs
src/part08.rs
src/part09.rs
src/part10.rs
src/part11.rs
src/part13.rs
src/part14.rs
src/part15.rs
src/part16.rs
workspace/src/part07.rs
workspace/src/part10.rs

index c20a47d07775f45fc7f9cd95287da4f2bdd80eeb..e1e4a6466db063d392893bd3753f7b099e1ba535 100644 (file)
@@ -2,7 +2,7 @@
 // ===================
 // 
 // 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).
 // 
@@ -117,4 +117,4 @@ fn main() {
 // * [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)
index bd8abf0dc5657d6378c68c51592de6c1f0f7d18c..1af74fc2fbfb0888aad916d83f106276aa827147 100644 (file)
@@ -22,7 +22,7 @@ pub use self::SomethingOrNothing::*;
 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
index ef8ab927112b5aaf2b0a8cd1678d3be03b747d1a..16527a2f71ce84d6415700cebf387a835d1fb69f 100644 (file)
@@ -29,14 +29,14 @@ fn read_vec() -> Vec<i32> {
     //@ 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.
 
index 8161d2d1d37dc6bd70bdda7b93f9779c36919dcb..4dff55c868b6d8e36c2d35c238c05b0deeb3fb80 100644 (file)
@@ -145,6 +145,6 @@ fn rust_foo(mut v: Vec<i32>) -> i32 {
 //@ 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)
index 4c143d5ae87dbe2ad169e97d8136d59ea72634b8..49f6900de95a5eab4698365debadeab0ec75739a 100644 (file)
@@ -62,8 +62,8 @@ impl PartialEq for BigInt {
 
 //@ 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
@@ -71,7 +71,7 @@ impl PartialEq for BigInt {
 //@ 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`.
@@ -113,7 +113,7 @@ fn test_min() {
 //@ 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;
 
index 7b471b9d827bdb1c6a5d47f836b334a9d9a1b714..ad29565d9b0ea3ffe925f2014487f3ba940975b7 100644 (file)
@@ -17,7 +17,7 @@ fn overflowing_add(a: u64, b: u64, carry: bool) -> (u64, bool) {
     //@ 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);
@@ -57,7 +57,7 @@ fn test_overflowing_add() {
 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
index 5a4f6662136204fb77a3cd22b0973a66e4b0b596..40e32a2281a7cd38e7f8e9a38090df287e7deaad 100644 (file)
@@ -5,7 +5,7 @@ use part05::BigInt;
 
 //@ 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.)
@@ -121,7 +121,7 @@ fn iter_invalidation_demo() {
 // ## 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
index 02fb82844762b276e145ca5b7b523eb37a862702..0522cb09e0d8cb8b743c41509449fb41af5cb785 100644 (file)
@@ -131,12 +131,12 @@ fn print_enumerated<T: fmt::Display>(v: &Vec<T>) {
 // 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!
index 9d093e38163296786605f76b1e2af38a6cc2592a..211cda5734ae9768ba62050dd0a5556c3cbe82e8 100644 (file)
@@ -102,7 +102,7 @@ pub fn main() {
 //@ 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.
index 9f42b8223771ee7a9c5d2d4bed804fdee30cf8f9..861ec2d6aaaf8605bc43a2b84f24e473a59ebd47 100644 (file)
@@ -167,7 +167,7 @@ pub fn main() {
 //@ 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`.
 
index 189a9060f8bf7fd195fb31409077a7a5dec1048a..2105838cacdd0ecffa2384bdba6ede66fb74b6fd 100644 (file)
@@ -69,7 +69,7 @@ fn sort_array() {
 
 // ## 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.
 //@ 
index 99eb3be10d2aa0ae96872c7c16e4c40d82e267ad..19ce603183f61209c284148db3c6d745dc9aad41 100644 (file)
@@ -11,7 +11,7 @@ use std::thread;
 //@ 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
@@ -103,7 +103,7 @@ pub fn main() {
 // 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
@@ -119,7 +119,7 @@ pub fn main() {
 //@ 
 //@ 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.
 //@ 
index dc26369e4c67919a8b6b87d5be4d6106b5d22f20..e80d80af913973ca1926efb4172af496664afb96 100644 (file)
@@ -55,7 +55,7 @@ pub struct LinkedList<T> {
 //@ 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
index 75bd0cca93c5fd006083406936ea00d97fd1e649..3ea4cc089e1679bd9e5de2a12fc34d0b85d350dc 100644 (file)
@@ -61,7 +61,7 @@ fn test_min() {
 
 // ## 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;
 
index c955394f11f12cf15211d7e6876ead12e63730e6..8fc650faaf2838c2cee04cc4b3bc630925faee7d 100644 (file)
@@ -92,7 +92,7 @@ fn filter_vec_by_divisor(v: &Vec<i32>, divisor: i32) -> Vec<i32> {
     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!