Rust 学习笔记

Rust 学习笔记

前情摘要

使用 Rust 完成的 Linux 代码的编写将要合入 Linux 主分支的事情激励我去学习 Rust 这门语言。个人感觉 Rust 会是未来 Kernel 乃至 System 的趋势,通过使用 Cargo 进行版本管理可以有效缓解 C 语言的版本问题,同时依赖模块类似于 Go 以及 Python 的第三方库下载可以有效解决 C 的死板的头文件以及依赖库问题,这些都是 Rust 的优势所在。更重要的是,通过引入生命周期的概念使得在运行时并不需要 GC 的这种我愿意称之为“语言归约”的设计,在运行性能上必然会优于 Java 和 Python,在内存泄漏问题上优于 C++,这也是我决心学习 Rust 的原因。

Rust 的学习方式比较多,我选择通过 Rustlings 这种类似于游戏的方式来学习 Rust 的各种知识。

我将我的解答开源在 GitHub 上,欢迎大家学习与围观。

Rustlings

Intro

Intro.1

这个问题就是展示一下 Rustlings 的图标,同时展示最简单的输出宏 println!,就和 C 语言的 printf 一样,是我们学习的基础。

Intro.2

这个问题希望我们输出 “Hello World”,一个点就是在 Rust 中 println! 格式串中的 {} 将会被替换成任意参数,结果如下所示:

    println!("Hello {}!", "World");

Variables

Variables.1

声明一个变量,需要加 let,如果不声明 mut 则默认为不可变变量。

    let x = 5;
    println!("x has the value {}", x);
Variables.2

这里变量 x 需要进行初始化,注意初始化的时候需要变量类型和变量初值。

    let x: i32 = 10;
    if x == 10 {
   
        println!("x is ten!");
    } else {
   
        println!("x is not ten!");
    }

注意 Rust 的变量初始化与 C 语言并不同,格式类似于变量:类型=初值

Variables.3

在这里变量 x 并没有初始化,Rust 编译器并不允许这种未赋值就使用的行为。

    let x: i32 = 100;
    println!("Number {}", x);
Variables.4

Rust 里面如果希望改变一个变量的值,需要定义为 mut 类型。

    let mut x = 3;
    println!("Number {}", x);
    x = 5; // don't change this line
    println!("Number {}", x);
Variables.5

在 Rust 中存在影子变量这中说法,这在 C 语言中是不允许的(会触发编译错误)。
实际上,在使用影子变量之后,编译器将仅仅只能看到后面的变量。

    let number = "T-H-R-E-E"; // don't change this line
    println!("Spell a Number : {}", number);
    let number = 3; // don't rename this variable
    println!("Number plus two is : {}", number + 2);

注意使用影子变量的方法是需要用 let 关键字。

Variables.6

实际上这里是 C 语言的写法,需要使用 Rust 自己的带类型赋值方法。

const NUMBER:i32 = 3;

Functions

Functions.1

这里实际上是对于函数 call_me,有使用但是没有声明,因此我们只需要声明一下即可。

fn call_me() {
   

}
Functions.2

这里函数的形参没有指定类型,需要指定类型

fn call_me(num: i32) {
   
    for i in 0..num {
   
        println!("Ring! Call number {}", i + 1);
    }
}
Functions.3

函数形参和实参并不匹配,这里需要在主函数加上实参。

    call_me(10);
Functions.4

Rust 在返回值设置上,并不像 C 语言那种使用 Return Statement 来标识返回值。而是通过最后一行是否使用分号决定返回的内容。同时在函数实现时需要使用 -> type 来标注函数的返回值。
此处需要补充的就是函数的返回值类型:

fn sale_price(price: i32) -> i32{
   
    if is_even(price) {
   
        price - 10
    } else {
   
        price - 3
    }
}
Functions.5

函数如果需要返回,则并不需要加分号。

fn square(num: i32) -> i32 {
   
    num * num
}

If

If.1

这里需要实现一个比大小的函数,注意 Rust 语法和 C 语法不一样的一点,Rust 的 If statement 部分并不需要加括号:

pub fn bigger(a: i32, b: i32) -> i32 {
   
    // Complete this function to return the bigger number!
    // Do not use:
    // - another function call
    // - additional variables
    if a > b {
   
        a
    } else {
   
        b
    }
}
If.2

这个需要根据下面的测试程序决定没一个输入应该输出什么字符串。

pub fn foo_if_fizz(fizzish: &str) -> &str {
   
    if fizzish == "fizz" {
   
        "foo"
    } else if fizzish == "fuzz" {
   
        "bar"
    } else {
   
        "baz"
    }
}

Quiz1

这个小测试实际上需要我们读懂上面的英文含义,并实现calculate_price_of_apples函数。
按照所叙述的要求,当购买数量超过 40 时,每个苹果 1 元,否则 2 元。

fn calculate_price_of_apples(cnt: i32) -> i32 {
   
    if cnt <= 40 {
   
        cnt << 1
    } else {
   
        cnt
    }
}

Primitive_types

Primitive_types.1

可以发现下面的变量 is_evening 有使用没有定义,再考虑到这里代码的语义,可以得到需要填写的代码:

    let is_evening = false; // Finish the rest of this line like the example! Or make it be false!
Primitive_types.2

这个是一个开放性问题,只需要对于 your_character 这个变量进行定义即可:

    let your_character = '3';
Primitive_types.3

这里我们需要定义数组,方式如下所示:

    let a = ["qaq"; 666];

这句话的含义为定义一个字符串数组,数组里面每一个元素均为 “qaq”,数组总长度为 666.

Primitive_types.4

这里实际上是 Rust 切片的应用。说到切片,就不得不提到所有权这个概念,实际上 Rust 对于地址的所有权管理是十分严格的。切片的变量实际上并不能获得地址的所有权的,仅仅是一个引用。
根据下面的测试程序,我们可以得到下面的代码:

    let nice_slice = &a[1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值