rust cheetsheet

Sat Dec 10 2022 · 10min

&str 和 String 的区别

简言之 &strString的子集,&str代表一个String Slice,

fn main() {
    let s = String::from("hello world"); // String type
    let hello = &s[0..5]; // &str type
    let world = &s[6..11];
}

另外&str类型表示的是一个不可变的 UTF-8 字符串切片,也就是内容不可变

fn main() {
    let s = "hello";
    s[0] = 'H'; // 报错:`&str` 类型的变量内容不可变
}

String 类型表示可变的 UTF-8 字符串,也就是说,String 类型的变量既可以指向一个固定的字符串,也可以动态地改变其值。

fn main() {
    let mut s = String::from("hello");
    s.push_str(", world!");
    println!("{}", s);  // 输出:hello, world!
}

borrow rule

  • 在任意时刻,只能存在一个 mutable 的指针或者多个 immutable 的指针
  • reference 必须总是有效(生命周期)

如何返回 local variable

https://doc.rust-lang.org/error_codes/E0515.html

在一个函数中创建的变量,rust 是不允许返回这个值的引用的,因为它的生命周期仅限于这个函数体, 所以如果你想返回这个本地创建的值,那么返回值类型就不能是borrowed, 例如String而不是&str, Vec<T>而不是&[T], T而不是&T

相当于把所有权交给了函数调用的地方

参考

当函数参数是一个借用值,怎么处理

首先入参的类型要不要加&, 取决于我们的入参变量在函数调用后还要不要被使用,如果不需要的话那就没必要传递指针,直接把所有权转移给函数即可。

fn test (input: String) -> String{

}

fn main(){
  let str = "hello";
  let _str = test(str);
}

模块导出约定

Many crates contain a prelude, a list of things that are convenient to import all at once. This allows common features of the module to be conveniently accessed without a lengthy prefix. F

一般会提供prelude用来导出一些通用 feature

静态链接 动态链接

静态链接是指将库文件的代码直接复制到可执行文件中,使得可执行文件中包含了全部所需的代码和数据,不再需要外部的库文件支持。

而动态链接是指可执行文件与库文件保持分离,运行时需要动态加载库文件。

在 Rust 中,使用静态链接可以将依赖库直接链接到应用程序中,从而减小应用程序的体积,同时也可以减少应用程序对系统环境的依赖。具体的原理如下:

编译器会将 Rust 应用程序编译为目标平台的机器码,同时生成一个符号表(Symbol Table),记录了应用程序所需的符号(比如函数、变量等)及其在可执行文件中的位置。

在编译时,Rust 编译器会将应用程序所需的库文件的代码直接复制到可执行文件中,并将符号表中对应的符号指向库文件中复制的代码段。

在运行时,操作系统加载可执行文件,并根据符号表中的信息找到对应的符号,执行库文件中复制的代码段。

因此,在静态链接的情况下,应用程序无需依赖外部的库文件,可以直接运行,从而减小了应用程序的体积,同时也减少了应用程序对系统环境的依赖。对于需要在不同的机器上运行的应用程序,使用静态链接还可以减少部署和配置的工作量,提高应用程序的可移植性。但是,静态链接的缺点是会增加可执行文件的体积和加载时间,并且不易更新库文件。

move

转移所有权,主要用于闭包,move 关键字是用来修改闭包的行为的,把对变量的所有权转移给闭包。

fn main() {
    let x = vec![1, 2, 3];
    let add = move |n| {
        x.iter().map(|i| i + n).collect::<Vec<_>>()
    };
    println!("{:?}", x); // fail, 因为闭包已经把变量x的所有权获取了 外边无法再使用x了
    let result = add(10);
}

Array or Vector

https://doc.rust-lang.org/book/ch03-02-data-types.html#the-array-type 根据官网给出,如果你不确定使用array还是vector,那么你很可能需要选择vector。但是我们有必要了解它俩的区别:

  1. 一般来说如果元素个数确定的话,比如月份这样的常量,你可以选择使用数组,它的类型声明如下:
let a: [i32; 5] = [1, 2, 3, 4, 5];
  1. 自然而然,元素个数不确定,非定长的时候我们可以选择 Vector,使用如下
let v: Vec<i32> = Vec::new();

    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);
Leave a comment
点击切换主题
... 人来过