
听说微软有开发者开始从事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被简写成了pubfunction简写为fn接口实现为impl6.Cargo 是 Rust 的构建系统和包管理器前面安装时会附带安上其作用类似maven之于springboot、npm之于node.js、pip之于python7. Rust 中变量默认是不可变的。一旦一个值绑定到一个名称 变量的值不能更改。变量可以通过以下方式使变量变动在变量名前添加 mut表示该变量定义的可变型变量let mut x 5; x 6;8.作为新语言融合了各种语法糖。为了降低歧义保留了分号作为一行代码的结束符没有像python、typescript那样。申明变量用let类比C#中var。9.代码中::不是继承因为没有继承用于关联函数和模块创建的命名空间我的理解其含义类似“来源于”也可用作大的库引用。10.所有权机制使 Rust 无需垃圾回收器也能提供内存安全保证。无需像C#和Java需要GCC需要亲自分配和释放内存。入栈比在堆上分配内存要快因为其位置总是在栈顶而堆上分配内存分配器必须首先找到一块足够存放。当代码调用一个函数时传递给函数的值和函数的局部变量被压入栈中当函数结束时这些值被移出栈。11.所有权规则Rust 中的每一个值都有一个 所有者owner值在任一时刻有且只有一个所有者当所有者离开作用域这个值将被丢弃。12.以下类型可以实现所有权的copy(我的理解就是值类型)所有整数类型比如u32。布尔类型bool它的值是true和false。所有浮点数类型比如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#一致因为不确定显示的具体格式、内容等这点上区别于TypeScript14.相比其他语言枚举支持更多类型结构体和枚举还有另一个相似点就像可以使用impl来为结构体定义方法那样也可以在枚举上定义方法。15.Rust 并没有空值不过它确实拥有一个可以编码存在或不存在概念的枚举。这个枚举是OptionT而且它定义于标准库中如下enum OptionT { None, Some(T), }为了拥有一个可能为空的值你必须要显式的将其放入对应类型的OptionT中。接着当使用这个值时必须明确的处理值为空的情况。只要一个值不是OptionT类型你就可以安全的认定它的值不为空。这是 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使用ResultT, E类型来处理可恢复错误使用panic!宏在程序遇到不可恢复错误时停止执行。大多数语言并不区分可恢复的recoverable和不可恢复的unrecoverable错误而是使用诸如异常exception之类的机制以相同方式处理它们。21.特殊的生命周期值得讨论static其生命周期能够存活于整个程序期间。