从零开始的Rusty Life

Wed Nov 29 2023

从零开始的Rusty Life

如你所见,我又开始开新坑了,起因是这样的,在写cpp的作业的时候被cpp的一堆《特性》给呛到了,故发表暴论:「有时间学这cpp,我还不如去学Rust

于是,就有了这个「从零开始的Rusty Life」,来记录一下我在 真・从零开始学习Rust的过程中遇到的各种坑

!!!WARNING!!!本文中可能会出现包括但不限与以下现象

  1. 直接复制Rust语言圣经Rust文档
  2. 直接跳过某些可能很重要的部分毕竟咱也不是写教程的,只是一个踩坑的记录而已,你要是要完整的你去看圣经啊
  3. 将Rust的某些特性与其他语言的某些特性进行不恰当的对比
  4. 一些排版问题或者拼写错误
  5. 以及各种不够到位的理解
  6. 还没想到之后再来补充总之再摸一会

最近更新于:2023-11-29(持 续 更muo 新yu 中)

## 从零开始的「Rust工具链安装 with rustup」

你好,我也不知道我什么时候装的rustup,总之就是我在写这段的时候,他已经装好了,vscode的插件什么的也都装好了,那就直接快进到创建项目8(没准之后哪天环境炸了,再回来重写这段

## 从零开始的「创建第一个项目」

刚想说这个我会,然后就发现有一个cargo init和一个cargo new……虽然这两个没什么区别就(吧

cargo new begin-rusty

Rust,启动!

打开自动创建的./src/main.rs,内容不多,只有这几行

fn main() {
    println!("Hello, world!");
}
 

但仔细一看,你这println怎么还是个macro啊(恼 算了,就先不纠结这个macro,先尝试看看点别的东西,圣经中直接写了一个带有迭代器的helloworld

fn main() {
    let southern_germany = "Grüß Gott!";
    let chinese = "世界,你好";
    let english = "World, hello";
    let regions = [southern_germany, chinese, english];
    for region in regions.iter() {
        println!("{}", &region);
    }
}

### let keyword

粘贴到vscode里面,会发现vscode能自动推导出变量的类型为&str[&str; 3]。这里简单分析一下这个声明变量的语句,首先查阅rust的docs,let关键字的作用就是Bind a value to a variable这个bind划重点,所以let有点类似于C#中的var和cpp的auto,由编译器在编译时推导出类型。吗?

有一个猜测,如果不给出一个能推导出具体类型的值(我也不确定是否存在这种情况)或者直接不给值应该是要报错的?那么合理发散一下,假如我现在就是只要声明一个变量占位,但是不想用一个值初始化,可行吗?(

然后我就在rust by example上面找到了一个例子,Declare first。很显然,let后面不加一个值来初始化,是可行的,你甚至都不用给他手动指定一个类型(比如let i: i32;),编译器都会自动完成。并且,假如你尝试给这个变量赋其他类型的值,居然还会报错(python你能不能学一学

let i;
i = 0;
i = "another type"; // mismatched types; expected `i32`, found `&str`
println!("{}", i);

### str type & & operator & ref keyword

以及这个&str文档这么说的

The str type, also called a 'string slice', is the most primitive string type. It is usually seen in its borrowed form, &str. It is also the type of string literals, &'static str.

这个&和cpp里面类似,也是表示一个引用,具体参见Primitive Type reference

A reference represents a borrow of some owned value. You can get one by using the & or &mut operators on a value, or by using a ref or ref mut pattern. For those familiar with pointers, a reference is just a pointer that is assumed to be aligned, not null, and pointing to memory containing a valid value of T

但是rust里面还有个关键字ref,这个ref&又有些区别

  • & denotes that your pattern expects a reference to an object. Hence & is a part of said pattern: &Foo matches different objects than Foo does.
  • ref indicates that you want a reference to an unpacked value. It is not matched against: Foo(ref foo) matches the same objects as Foo(foo).

### array type

数组也是rust的基本类型之一,rust的数组的声明也和别的语言的写法有点不一样,let regions: [&str; 3],其中3是数组长度,如果与实际初始化的长度不符,编译器会报错。

A fixed-size array, denoted [T; N], for the element type, T, and the non-negative compile-time constant size, N.

数组还有两种创建方法,列出所有元素,或者重复某一个表达式N次

  • A list with each element, i.e., [x, y, z].
  • A repeat expression [expr; N] where N is how many times to repeat expr in the array. expr must either be:
    • A value of a type implementing the Copy trait
    • A const value

此外,数组还有一个特性,即为切片 (Slice)

Arrays coerce to slices ([T]), so a slice method may be called on an array. Indeed, this provides most of the API for working with arrays.

切片的内容也好多,下次再写

### for keyword

关键字 for有几种用法,其一便是上文中的for loop_variable in iterator用法,iterator是一个迭代器,regions.iter()便是在显式地将一个数组变为迭代器;但是从某个版本开始,rust支持直接使用数组进行迭代,会隐式地将数组转换为迭代器,所以此处写成for region in regions也是可以的。

绷不住了,怎么一个helloworld都看不懂啊

## 一些碎碎念

唉这个rust啊,想学很久了,但是一直没有什么动力,曾经某位神有名言:

Reverier: 学一门语言花一上午还不够(?)

但这个rust,一是因为和平时写的别的语言(C#、TypeScript。Python)差别确实大的多,在写的时候的思路不能简单复用,真的做不到一个上午学完啊草,连语法都学不完。

但是不得不说,rust的有些特性确实挺吸引人的,这也是我目前学rust的动力吧(虽然感觉随时都有弃坑的可能性

## To Be Continued ...

你要不要看一下站点名称:「摸鱼日记」,所以后面摸了 下次一定🥺(