Rust语言基础入门学习记录
2026/7/14 6:38:54 网站建设 项目流程

听说微软有开发者开始从事C#转Rust语言,想简单学习下非GC的软件开发,做到能看得懂代码。这篇也是跟随微软的文档做的个人理解和记录,Git链接https://github.com/microsoft/RustTraining,该仓库包含多本“桥梁书”,涉及C#、Python、C++等转Rust的一些文档资料:

另有独立的在线指南,由微软官方维护C#/.NET 开发者编写的 Rust 指南:https://microsoft.github.io/rust-for-dotnet-devs/latest/

Rust入门指南,该中文版由Rust中文项目组维护,持续跟随官方版本更新,简体中文版:https://rustwiki.org/zh-CN/book/


有这几个文档,入手的话应该够了,这里记录的是看这几个文档中的一些思考记录。

1.安装环境,环境的安装windows需要访问 安装 Rust - Rust 程序设计语言 页面并按照说明安装 Rust,安装完成后在命令行输入rustc --version将能够看到版本信息

2.Rust 文件通常以.rs扩展名结尾,联系C#是.cs结尾,java就是.java结尾,Python是.py结尾

3.基础数据类型相差不大,整型多个128位的Int128和UInt128。注意Rust中一个字符是4字节Unicode,不再是两个字节UTF-16 encoding,新的语言为了适应更多场景扩大了字节。

4.Rust去掉了类的概念,保留了结构体struct,不必太在意继承和多态,通过traits类似于接口实现,因此没有等价于protected关键字

5.Rust标准也注重简写,其本身的关键字也是简写,public被简写成了pub,function简写为fn,接口实现为impl,

6.Cargo 是 Rust 的构建系统和包管理器,前面安装时会附带安上,其作用类似maven之于springboot、npm之于node.js、pip之于python

7. Rust 中,变量默认是不可变。一旦一个值绑定到一个名称, 变量的值不能更改。变量可以通过以下方式使变量动,在变量名前添加 mut表示该变量定义的可变型变量:let mut x = 5; x = 6;

8.作为新语言,融合了各种语法糖。为了降低歧义,保留了分号;作为一行代码的结束符,没有像python、typescript那样。申明变量用let,类比C#中var。

9.代码中::不是继承,因为没有继承,用于关联函数和模块创建的命名空间,我的理解其含义类似“来源于”,也可用作大的库引用。

10.所有权机制使 Rust 无需垃圾回收器,也能提供内存安全保证。无需像C#和Java需要GC,C++需要亲自分配和释放内存。入栈比在堆上分配内存要快,因为其位置总是在栈顶,而堆上分配内存分配器必须首先找到一块足够存放。当代码调用一个函数时,传递给函数的值和函数的局部变量被压入栈中,当函数结束时,这些值被移出栈。

11.所有权规则:Rust 中的每一个值都有一个 所有者(owner);值在任一时刻有且只有一个所有者;当所有者离开作用域,这个值将被丢弃。

12.以下类型可以实现所有权的copy(我的理解就是值类型):

  • 所有整数类型,比如u32
  • 布尔类型,bool,它的值是truefalse
  • 所有浮点数类型,比如f64
  • 字符类型,char
  • 元组,当且仅当其包含的类型也都实现Copy的时候。比如,(i32, i32)实现了Copy,但(i32, String)就没有。

这个代码很有说明性:

fn main() { let s = String::from("hello"); // s 进入作用域 takes_ownership(s); // s 的值移动到函数里 ... // ... 所以到这里不再有效 let x = 5; // x 进入作用域 makes_copy(x); // x 应该移动函数里, // 但 i32 是 Copy 的, println!("{}", x); // 所以在后面可继续使用 x }

13.Rust 并不允许直接println打印结构体,这跟java、C#一致,因为不确定显示的具体格式、内容等,这点上区别于TypeScript

14.相比其他语言枚举支持更多类型,结构体和枚举还有另一个相似点:就像可以使用impl来为结构体定义方法那样,也可以在枚举上定义方法。

15.Rust 并没有空值,不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是Option<T>,而且它定义于标准库中,如下:

enum Option<T> { None, Some(T), }

为了拥有一个可能为空的值,你必须要显式的将其放入对应类型的Option<T>中。接着,当使用这个值时,必须明确的处理值为空的情况。只要一个值不是Option<T>类型,你就可以安全的认定它的值不为空。这是 Rust 的一个经过深思熟虑的设计决策,来限制空值的泛滥以增加 Rust 代码的安全性。

16.match相比大部分语言的switch,虽然都用于控制流结构,match的力量来源于模式的表现力,以及编译器能够确认所有可能情况均已被覆盖。对于if,表达式必须返回一个布尔值,而这里它可以是任何类型的。其中的other相当于其他语言的default,只是other必须位于match中最末。

17.Rust遍历集合更想让你知道这个地址的迭代遍历,而不是值得循环,例如下方遍历加了&

let v = vec![100, 32, 57]; for i in &v { println!("{i}"); }

而要对此值进行赋值处理,要采用解引用符号,也就是必须先使用解引用运算符*取到i指向的值,也含有此思想内核:

let mut v = vec![100, 32, 57]; for i in &mut v { *i += 50; }

18.在很多语言中,通过索引来引用字符串中的单独字符是有效且常见的操作。然而在 Rust 中,如果你尝试使用索引语法访问String的一部分,会出现一个错误,如下代码会报错:

let s1 = String::from("hi"); let h = s1[0];

19.Rust中遍历哈希 map 会以任意顺序进行,Hash map 提供了一个特殊的 API,叫做entry,它接收你想检查的键作为参数。

let mut scores = HashMap::new(); scores.insert(String::from("Blue"), 10); scores.entry(String::from("Blue")).or_insert(50);

Entry上的or_insert方法被定义为:如果对应Entry的键已经存在,就返回该值的可变引用;如果不存在,就把参数作为这个键的新值插入,并返回这个新值的可变引用。

20.Rust使用Result<T, E>类型来处理可恢复错误,使用panic!宏在程序遇到不可恢复错误时停止执行。大多数语言并不区分可恢复的recoverable)和不可恢复的unrecoverable)错误,而是使用诸如异常(exception)之类的机制以相同方式处理它们。

21.特殊的生命周期值得讨论:'static,其生命周期能够存活于整个程序期间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询