Learn Rust by Rustlings

最近正在学习 Rust,发现了一个不错的学习资源,叫做 Rustlings,是一个 Rust 的练习项目,可以帮助快速上手 Rust。

使用方式也很简单,如果是 macOS,那么可以直接使用下面的命令开始,它会检查当前环境,并在当前目录下安装rustlings


curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash

安装完成之后可以使用 cd rustlings 进入到 rustlings 目录下,所有的题目都会在 ./exercises 目录里面,

> cat exercises/README.md 
# Exercise to Book Chapter mapping

| Exercise               | Book Chapter        |
| ---------------------- | ------------------- |
| variables              | §3.1                |
| functions              | §3.3                |
| if                     | §3.5                |
| primitive_types        | §3.2, §4.3          |
| vecs                   | §8.1                |
| move_semantics         | §4.1-2              |
| structs                | §5.1, §5.3          |
| enums                  | §6, §18.3           |
| strings                | §8.2                |
| modules                | §7                  |
| hashmaps               | §8.3                |
| options                | §10.1               |
| error_handling         | §9                  |
| generics               | §10                 |
| traits                 | §10.2               |
| tests                  | §11.1               |
| lifetimes              | §10.3               |
| iterators              | §13.2-4             |
| threads                | §16.1-3             |
| smart_pointers         | §15, §16.3          |
| macros                 | §19.6               |
| clippy                 | §21.4               |
| conversions            | n/a                 |

这个使用就可以使用我们属性的编辑器来进行开发了,如果使用的是 VSCode,那么可以直接使用 code . 就可以直接以当前目录下打开,这个时候我们在终端运行 rustlings watch 就可以看到当前的题目了。 每次完成一道题目以后,我们可以通过删除 // I AM NOT DONE 来进行下一道题目,如果想要查看当前题目的答案,可以使用 rustlings hint 来查看。 好啦,开始愉快得刷题吧!

错题记录

1. vecs2.rs

要修改 vec_loopvec_map 两个函数,使得它们可以正确的运行。 vec_loop 中需要使用 iter_mut 来进行可变的迭代,取到每一个元素的可变引用,然后进行修改。

fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
    for mut element in v.iter_mut() {
        // TODO: Fill this up so that each element in the Vec `v` is
        // multiplied by 2.
        *element *= 2;
    }

    // At this point, `v` should be equal to [4, 8, 12, 16, 20].
    v
}

vec_map 中需要使用 map 来进行迭代,取到每一个元素的引用,然后进行修改,最后使用 collect 来收集所有的元素。

fn vec_map(v: &Vec<i32>) -> Vec<i32> {
    v.iter()
        .map(|element| {
            // TODO: Do the same thing as above - but instead of mutating the
            // Vec, you can just return the new number!
            element * 2
        })
        .collect()
}

2. move_semantics5.rs

fn main() {
    let mut x = 100;
    let y = &mut x;
    let z = &mut x;
    *y += 100;
    *z += 1000;
    assert_eq!(x, 1200);
}

问题的原因是在同一个作用域下,不能同时存在多个可变引用,所以需要将 yz 的作用域分开。

fn main() {
    let mut x = 100;
    {
        let y = &mut x;
        *y += 100;
    }
    let z = &mut x;
    *z += 1000;
    assert_eq!(x, 1200);
}