Rust学习_2.通用集合类型

通用集合类型

  • Vector, 动态数组
  • String,字符串
  • Hashmap,哈希映射

一、Vector

  • 由标准库提供;
  • 可存储多个值;
  • 只能存储相同类型的数据;
  • 值在内存中连续存放。

1.1 创建Vector

1
2
3
4
5
fn main(){
let v:Vec<i32> = Vec::new(); // 方法一

let v1 = vec![1,2,3]; // 方法二
}

1.2 更新Vector

向Vector添加元素,使用push方法;

1.3 删除Vector

与任何其他 struct一样,当Vector离开作用域后

- 它就被清理掉;
- 它所有的元素也被清理掉;

1.4 读取Vector元素

  1. 索引方式
    • 越界:panic
  2. get方法
    • 越界:返回None

1.5 所有权和借用规则

  • 不能在同一作用域内同时拥有可变和不可变引用;
1
2
3
4
5
6
fn main(){
let mut v = vec![1,2,3,4,5];
let first = &v[0]; // immutable borrow occurs here
v.push(6); // 报错:mutable borrow occurs here
println!("The first element is {}",first);
}

由于Vector中的值在内存中连续存储,所以当往数组尾部push数据时,数组地址可能会迁移,头节点的地址会改变。

1.6 遍历Vector

  • for 循环

1.7 使用enum存储多种数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
enum SpreadsheetCell{
Int(i32),
Float(f64),
Text(String),
}

fn main(){
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Float(10.23),
SpreadsheetCell::Text(String::from("blue")),
];
}

二、String类型

0. Rust开发者经常会被字符串困扰原因

  1. Rust 倾向于暴露可能的错误;
  2. 字符串数据结构复杂;
  3. UTF-8;

1. 字符串是什么?

  • 语言核心部分:字符串切片str ,通常以借用的形式(&str)出现,指向存储在别处的utf-8编码字符串的引用;
  • 标准库中String类型;

2. 创建一个新的字符串

1
2
3
4
5
fn main(){
let s1 = String::from("hello world");// 方法一

let s2 = "hello world".to_string();// 方法二
}

3. 更新String

  • push_str()方法:把一个字符串切片附加到String;

  • push()方法:把单个字符附加到 String;

  • + : 连接字符串:夺取第一个数据所有权;

    1
    2
    3
    let s1 = String::from("Hello,");
    let s2 = String::from("world!");
    let s3 = s1 + &s2; // 注意,这里的s1已经被移动且再也不能被使用了!

    我们在加法操作中仅对s2采用了引用,而s1在加法操作之后则不再有效。这里的+运算符会调用一个add()方法:

    1
    fn add(self, s:&str)->String{}
  • format! 宏:不会夺取任何参数所有权;

    1
    2
    3
    4
    5
    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");

    let s = format!("{}-{}-{}",s1,s2,s3);

4. 字符串索引

Rust 中的字符串并不支持索引!

  1. 字符串中字节的索引并不总是对应到一个有效的Unicode标量值,String 实际上是一个基于Vec的封装类型,使用UTF-8编码!

  2. 字节、标量值、字形簇

    • 字节: u8
    • 标量值:char
    • 字形簇:最接近人们眼中的 字母。
  3. 无法保障索引性能,因为Rust必须要遍历从头至索引位置的整个内容来确定究竟有多少合法的字符存在。

5. 字符串切片

通过索引引用字符串通常是一个坏主意,因为字符串索引操作应当返回的类型是不明确的:究竟应该是字节、字符还是字形簇?

  • 切片时范围语法不当会导致程序panic;

6. 遍历字符串

  • "".chars();
  • "".bytes();