RUST 学习日记 第9课 ——复合数据类型

98 阅读3分钟

0x01 数据类型

数组声明

在Rust中数组的类型签名为: [T;N]T表示数据类型,N表示数组的长度,编译时必须确定其大小。数组有以下两种初始化方式:

1、中括号中列举所有的值,其中的值以英文逗号隔开。 2、中括号中,第一个值表示默认初始元素,第二个值表示长度,中间使用英文分号;隔开。 元组是有一个或多个类型的元素组合而成的复合类型。官方没有给出明确定义。在使用过程中,元组通常至少包含两个元素。当然元组只包含一个元素也可以,没有元素也是可以的。

元组声明

元组是一种异构有限的序列。异构表示元组内的元素可以是不同类型的。有限是指元组的长度是固定的。元组的签名格式为: (T,U,M) ,T,U,M均表示类型。

fn main() {
    //数组
    let d = [2,2,2,2,2];
    println!("The value   of array  at 0 is {} ",d[0]);
    let d:[i32;5] = [2;5];
    println!("The value   of array  at 0 is {} ",d[0]);
    //元组
    let tup:(i32,f64,bool) = (20,3.14,false);
    println!("tuple value is {}",tup.0);
    let (x,y,z) = tup;
    println!("x {} y {} z {}",x,y,z);

}

0x02 切片(slice)

字符串切片

let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];

let world = &s[6..11]; 来说,world 是一个切片,该切片的指针指向 s 的第 7 个字节(索引从 0 开始, 6 是第 7 个字节),且该切片的长度是 5 个字节。 image.png

let s = String::from("hello world");
let len = s.len();
//切片到最后一个字节
let slice = &s[4..len];
let slice = &s[4..];
let slice = &s[..];

在对字符串使用切片语法时需要格外小心,切片的索引必须落在字符之间的边界位置,也就是 UTF-8 字符的边界,例如中文在 UTF-8 中占用三个字节,下面的代码就会崩溃:

let s = "中国人";
let a = &s[0..2];
println!("{}",a);

因为我们只取 s 字符串的前两个字节,但是本例中每个汉字占用三个字节,因此没有落在边界处,也就是连  字都取不完整,此时程序会直接崩溃退出,如果改成 &s[0..3],则可以正常通过编译。 因此,当你需要对字符串做切片索引操作时,需要格外小心这一点, 关于该如何操作 UTF-8 字符串,参见这里

数组切片

let a = [1,2,3,4,5];
let slice = &a[1..3];
assert_eq!(slice,&[2,3]);

字符串

顾名思义,字符串是由字符组成的连续集合,但是在上一节中我们提到过,Rust 中的字符是 Unicode 类型,因此每个字符占据 4 个字节内存空间,但是在字符串中不一样,字符串是 UTF-8 编码,也就是字符串中的字符所占的字节数是变化的(1 - 4) ,这样有助于大幅降低字符串所占用的内存空间。

Rust 在语言级别,只有一种字符串类型: str,它通常是以引用类型出现 &str,也就是上文提到的字符串切片。虽然语言级别只有上述的 str 类型,但是在标准库里,还有多种不同用途的字符串类型,其中使用最广的即是 String 类型。

str 类型是硬编码进可执行文件,也无法被修改,但是 String 则是一个可增长、可改变且具有所有权的 UTF-8 编码字符串,当 Rust 用户提到字符串时,往往指的就是 String 类型和 &str 字符串切片类型,这两个类型都是 UTF-8 编码

除了 String 类型的字符串,Rust 的标准库还提供了其他类型的字符串,例如 OsString, OsStr, CsString 和 CsStr 等,注意到这些名字都以 String 或者 Str 结尾了吗?它们分别对应的是具有所有权和被借用的变量。