rust 初探 -- 常用的集合

rust 初探 – 常用的集合

Vector

存储在堆内存上的数据,运行时可以动态变大或者变小。
Vec 特性:

  • 由标准库提供,可以存储多个相同类型的值,并且值在内存中连续存放

Vector 的创建

fn main() {
    // Vec::new()
    let v: Vec<i32> = Vec::new();
    // 使用初始值创建,使用 vec! 宏
    let v1 = vec![1,2,3];
}

更新 Vector

fn main() {
    //这里不需要指明 vec 的类型,因为后面有 push 操作会自己推断出来
    let mut v = Vec::new();
    v.push(1);
}

删除 Vector

和其他的 struct 结构体一样,当 Vector 离开了作用域,就会被清理掉
如果涉及到引用会不一样。

读取 Vector 的元素

fn main() {
    let v = vec![1,2,3,4,5];
    let third = &v[2]; // 1. 使用索引,非法访问 panic
    println!("{}", third);

    match v.get(2) { // 2. get 方法,非法访问 返回 None
        Some(third) => println!("get {}", third),
        None => println!("not exist"),
    }
}
所有权和借用规则

不能在同一作用域里,对一个值不能同时有可变和不可变的引用

//vec 中内存中是连续的,新增的时候可能会重新分配,所以直接不让这样操作
fn main() {
    let mut v = vec![1,2,3,4,5];
    let third = &v[2]; //不可变的
    
    v.push(6); //mutable borrow occurs here

    println!("{}", third);
}
遍历 Vector 的值
fn main() {
	let mut v = vec![1,2,3,4,5];
	for i in &mut v {
		*i += 50;
	}
	for i in v {
		println!("{}", i);
	}
}
使用 enum 来存储多种数据类型
  • enum 的变体可以附加不同类型的数据
  • enum 的变体定义在同一个 enum 类型下
enum Cell {
	Int(i32),
	Float(f64),
	Text(String),
}
// 因为类型不同,枚举的时候不好操作(很多个),需要使用到 trait 对象
fn main() {
	//编译时就知道堆上要多大的内存,而且知道所有的可能情况,编译时可以做检查
	let row = vec![
		Cell::Int(3),
		Cell::Float(10.1),
		Cell::Text(String::from("text")),
	];
}

字符串是什么

  • Rust 的核心语言层面,只有一个字符串类型:字符串切片 str(或&str)

  • 字符串切片:对存储在其他地方、UTF-8编码的字符串的引用

    • 字符串字面值:存储在二进制文件中,也是字符串切片
  • String 类型:

    • 来自标准库而不是核心语言
    • 可增长、可修改、可拥有

通常说的字符串是指?

String 和 &str

  • 特性:utf-8 编码

其他类型的字符串

  • OsString,OsStr,CString,Cstr
  • 还有一些其他第三方库

创建一个新的字符串

String::new()//用于创建一个空的字符串,是可变的
to_string()	//方法,可用于实现了 displag trait 的类型,包括字符串字面值
String::from() //函数,从字面值来创建字符串

更新 String

  • push_str() 方法:字符串切片
fn main() {
	let mut s1 = String::from("foo");
	s1.push_str("bar");//- push_str() 方法:字符串切片

	println!("{}", s1); // foobar

	s1.push('b');//- push() 方法:单个字符
	println!("{}", s1); // foobarb
}
    • 操作符,拼接字符串
fn main() {
	let s1 = String::from("foo");
	let s2: String = String::from("bar");
	
	let s3 = s1 + &s2;
	//相当于 fn add(self, s: &str) -> String {}
	//&String 强制转换成 &str,解引用强制转换(deref coercion),会保留 s2 的所有权

	println!("{}", s3);
	// println!("{}", s1);//error[E0382]: borrow of moved value: `s1`
	// println!("{}", s2);
}
  • format!:不会取得任意参数的所有权
use std::fmt::format;

fn main() {
	let s1 = String::from("foo");
	let s2: String = String::from("bar");
	let s3: String = String::from("car");
	
	// let s4 = s1 + "-" + &s2 + "-" + &s3;
	// println!("{}", s4); //foo-bar-car
	
	let s5 = format!("{}-{}-{}", s1, s2, s3);
	println!("{}", s5);//foo-bar-car
}

内部表示

  • String 是对 Vex 的包装
 String::from("hola").len(); //4,返回字节数
 // unicode 标量值
字节,标量值,字形簇
fn main() {
	let w = "测试一下";
	for b in w.bytes() {//字节
		print!("{} ", b)//230 181 139 232 175 149 228 184 128 228 184 139 
	}
	for b in w.chars() {//标量值
		print!("{} ", b)// 测 试 一 下
	}
}
访问 String
  • 不支持按索引语法形式进行访问:
    • 不同语言的字符串,其对应的字节数不同
    • 索引操作应消耗一个常量时间(O(1)),而String 无法保证,需要遍历所有内容来确定有多少个合法的字符
切割 String
s = &hello[0..4]; //但是切割必须沿着字符的边界切割,否则会panic

HashMap<K, V>

  • 键值对的形式存储数据
  • 适合场景,通过 K (任何类型)来寻找数据,而不是通过索引

创建 HashMap

use std::collections::HashMap;

fn main() {
	//创建 HashMap
	let mut scores = HashMap::new();
	scores.insert(String::from("bob"), 99); //会基于此推断 k,v的类型
	// 不在 Prelude 中,所以需要添加 use 
	
	//2. collect()
	let team = vec![String::from("a"), String::from("b")];
	let t_scores = vec![10,12];
	let hp: HashMap<_, _> = team.iter().zip(t_scores.iter()).collect();
	// 需要指明 HashMap<_, _>
}
  • 数据存储在 heap 上
  • 同构的:一个 HashMap 中,所有 k 必须是同一类型,所有 v 必须是同一类型

HashMap 和所有权

  • 对于实现了 Copy trait 的类型,值会被复制到 HashMap 中
  • 对于拥有所有权的值(如 String),值会被移动,所有权会被转移给 HashMap
  • 如果将值的引用插入到 HashMap,值本身不会移动 (被引用的值需要有效)
fn main() {
	let name = String::from("key");
	let value = String::from("value");

	//创建 HashMap
	let mut scores = HashMap::new();
	// scores.insert(name, value);

	// print!("{}:{}", name, value); // value borrowed here after move
	scores.insert(&name, &value);

	println!("{}:{}", name, value);//key:value
}

访问 HashMap

  • get 方法,参数 K,返回 Option<&V>
use std::collections::HashMap;

fn main() {
	//创建 HashMap
	let mut scores = HashMap::new();
	scores.insert(String::from("bob"), 90);
	scores.insert(String::from("lili"), 100);

	let name = String::from("bob");
	let score = scores.get(&name);

	match score {
		Some(s) => println!("{}", s), // 90
		None => println!("team not exist"),
	};
} 

遍历 HashMap

use std::collections::HashMap;

fn main() {
	//创建 HashMap
	let mut scores = HashMap::new();
	scores.insert(String::from("bob"), 90);
	scores.insert(String::from("lili"), 100);

	for (k, v) in &scores {
		println!("{}-{}", k, v)//lili-100 bob-90
	}
}

更新 HashMap

  • HashMap 大小可变,每个 K 只能对应一个 V
  • 更新 HashMap 中的数据,已存在 K,或者不存在 K
use std::collections::HashMap;

fn main() {
	//创建 HashMap
	let mut scores = HashMap::new();
	scores.insert(String::from("bob"), 90);
	scores.insert(String::from("lili"), 100);

	//1. 替换现有的 v,插入两个相同k,不同 v,前者会被后者替换
	//2. 只在 K 不存在时,才插入 v
	//使用 entry 方法,结合 or_insert 
	scores.entry(String::from("bob")).or_insert(80);
	scores.entry(String::from("bob2")).or_insert(80);

	println!("{:#?}", scores)
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Mac Rust io-uring是一种在Mac操作系统上使用Rust语言进行开发的io-uring库。 io-uring是Linux内核中的一个新特性,它为应用程序提供了一种高性能、高效率的异步I/O操作方式。它通过使用事件驱动和无锁技术,实现了在高并发环境下进行文件操作的优化。io-uring提供了更低的系统开销和更高的吞吐量,特别适用于需要大量I/O操作的应用程序。 虽然io-uring最初是为Linux内核设计的,但由于其高性能的特性,一些开发者试图将其移植到其他操作系统上。其中,Mac Rust io-uring就是一个在Mac操作系统上使用Rust语言实现io-uring的库。 使用Mac Rust io-uring,开发者可以在Mac环境下利用io-uring的特性来提高文件操作的性能。这对于需要进行大量I/O操作的应用程序来说,是一个很有价值的工具。例如,对于数据库、Web服务器或文件传输等应用,通过使用Mac Rust io-uring,可以显著提高其性能和吞吐量。 Mac Rust io-uring不仅提供了对io-uring的封装,还提供了一些更高级别的功能和接口,以方便开发者使用。开发者可以使用Mac Rust io-uring来实现一些高级的文件操作,例如批量读取或写入文件,提高数据处理的效率。 总之,Mac Rust io-uring是一个在Mac操作系统上使用Rust语言开发的io-uring库,它能够为开发者提供高性能的异步I/O操作方式,从而提高应用程序的性能和吞吐量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jiangw557

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值