rust

rust众多数据类型可以高效利用底层空间

// rust中的基本类型
// 整数类型
// 有符号整数
let _i8: i8 = 0;
let _i16: i16 = 0;
let _i32: i32 = 0;
let _i64: i64 = 0;
let _i128: i128 = 0;
let _isize: isize = 0;
// 无符号整数
let _u8: u8 = 0;
let _u16: u16 = 0;
let _u32: u32 = 0;
let _u64: u64 = 0;
let _u128: u128 = 0;
let _usize: usize = 0;
// 浮点数类型
let _f32: f32 = 0.0;
let _f64: f64 = 0.0;
// 布尔类型
let _bool: bool = true;
// 字符类型
let _char: char = 'a';
// 数组类型
let _array: [i32; 5] = [1, 2, 3, 4, 5]; 
// 元组类型
let _tuple: (i32, f64, u8) = (500, 6.4, 1);
// 元组的解构
let (_x, _y, _z) = _tuple;
println!("The value of y is: {}", _y);
// 元组的索引
let _five_hundred = _tuple.0;
let _six_point_four = _tuple.1;
let _one = _tuple.2;

所有权

所有权规则

首先,让我们看一下所有权的规则。当我们通过举例说明时,请谨记这些规则:

  1. Rust 中的每一个值都有一个 所有者owner)。

  2. 值在任一时刻有且只有一个所有者。

  3. 当所有者(变量)离开作用域,这个值将被丢弃。

变量作用域

硬编码字符串(字面量),仅在作用域内有效

String

Rust 有第二个字符串类型,String。这个类型管理被分配到堆上的数据,所以能够存储在编译时未知大小的文本。可以使用 from 函数基于字符串字面值来创建 String,如下:

使其可修改

对于 String 类型,为了支持一个可变,可增长的文本片段,需要在堆上分配一块在编译时未知大小的内存来存放内容。这意味着:

  • 必须在运行时向内存分配器(memory allocator)请求内存。

  • 需要一个当我们处理完 String 时将内存返回给分配器的方法。

变量与数据交互的方式(一):移动

为了确保内存安全,在 let s2 = s1 之后,Rust 认为 s1 不再有效,因此 Rust 不需要在 s1 离开作用域后清理任何东西。

Rust 永远也不会自动创建数据的 “深拷贝”。因此,任何 自动 的复制可以被认为对运行时性能影响较小。

变量与数据交互的方式(二):克隆

如果我们 确实 需要深度复制 String 中堆上的数据,而不仅仅是栈上的数据,可以使用一个叫做 clone 的通用函数。第五章会讨论方法语法,不过因为方法在很多语言中是一个常见功能,所以之前你可能已经见过了。

只在栈上的数据:拷贝

所有权与函数

将值传递给函数与给变量赋值的原理相似。向函数传递值可能会移动或者复制

返回值与作用域

返回值也可以转移所有权

引用

引用reference)像一个指针,因为它是一个地址,我们可以由此访问储存于该地址的属于其他变量的数据。 与指针不同,引用确保指向某个特定类型的有效值

&s1 语法让我们创建一个 指向s1 的引用,但是并不拥有它。因为并不拥有这个值,所以当引用停止使用时,它所指向的值也不会被丢弃。

可变引用

可变引用有一个很大的限制:如果你有一个对该变量的可变引用,你就不能再创建对该变量的引用。这些尝试创建两个 s 的可变引用的代码会失败:

不同作用域可以拥有同一引用

哇哦!我们 也 不能在拥有不可变引用的同时拥有可变引用。

可以

引用的规则

让我们概括一下之前对引用的讨论:

  • 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。

  • 引用必须总是有效的。

Slice 类型

slice 允许你引用集合中一段连续的元素序列,而不用引用整个集合。slice 是一类引用,所以它没有所有权。

world containing a pointer to the byte at index 6 of String s and a length 5

结构体

Last updated