📚 Vector
创建时间:
2023-04-01 02:34 星期六
创建
let mut v : Vec<i32>= Vec::new();
// 创建一个空的 Vector
let mut v2 : Vec<i32> = vec![1,2,3];
// 默认有值的 Vector 可以不用显式指定类型
操作
fn main() {
let mut v = Vec::new();
for i in 1..101{
v.push(i);
}
println!("{:?}", v);
}
编译器知道我们在后面会有 push(i32)的存在所以就在创建 vector 的时候不用指定类型了!
索引
fn main() {
let mut v = Vec::new();
... // 同上
// Get 方式获取
match v.get(2){
Some(value)=>{
println!("存在一个数据他的值是{value}")
},
None=>{
println!("什么都没有呢!")
}
}
// 索引方式获取
let value = &v[2];
println!("索引为2的值是{}", value)
}
如果使用索引的方式 索引超出了范围就会报错 而 match 不会。
Vector 和 Enum
如果我们想在 vector 中存放不同类型的数据 我们可以
enum Data {
STRING (String),
INT (i32),
BOOLEAN (bool)
}
fn main(){
let v = vec![
Data::STRING(String::from("你好")),
Data::INT(42),
Data::BOOLEAN(true)
];
}
📚 字符串
创建时间:
2023-04-01 03:40 星期六
创建 String
fn main(){
let new_string = String::new();
// 新建字符串
let mut init_string = "你好啊".to_string();
// 初始化字符串
init_string = String::from("这个就不多说了");
}
修改
fn main(){
let mut new_string = String::new();
new_string.push_str("新的数据追加");
new_string += &String::from("追加的字符串");
new_string = new_string + &String::from("追加的字符串"); // + 左边的不是引用 右边的是引用
println!("{}", new_string);
}
那我们这么做呢?
let tmp = String::from("新的字符串");
let new_tmp = new_string + &tmp;
print!("{}", new_string);
会报错: 因为 在上述代码的第二行中类似调用了 fn add(self, b: &str)
的函数, 会夺走第一个参数的所有权导致之后的字符串无作用。
所以我们得这么写:
let tmp = tmp + &String::from("你好啊") + &String::from("我不在");
好麻烦!
所以我们推荐这么做:
let tmp = String::from("新的字符串");
let tmp = format!("{}-{}-{}", tmp,String::from("你好啊"), String::from("我不在"));
println!("{}", tmp);
索引
直接使用 val[1] 获取字符串 val 的第 2 个字符是错误的!
为什么? 因为字符串是 utf-8 类型的 其中 utf-8 的字节长度不一,按中文举例子 1 个汉字的长度是 3,但是 i[1]的死后拿到的是这个汉字的第二个字节 不能够拿到期望的数据 所以报错
所以我们需要了解三个东西: 字节 标量值 字形簇
fn main(){
let value = String::from("你是我的谁");
print!("---------[字节]------------");
for i in value.bytes(){
println!("{}", i);
}
print!("---------[unicode 标量]------------");
for i in value.chars(){
println!("{}", i);
}
print!("---------[字符簇]------------");
let x = "不必了解";
}
打印结果如下
....
231
154
132
232
176
129
你
是
我
的
谁
字符串的切片
这个我们之前有讲过。切割字符串是允许的 但是我们切片中文的时候 如果切片是 [1..2] 切了半个中文,似乎会报错。
但是我们可以这么做:
let begin = value.char_indices().nth(4).unwrap().0 as usize; // 第4个元素的真实索引 从0开始
let end = value.char_indices().nth(8).unwrap().0 as usize; //第8个元素的真实索引 从0开始
print!("{}", &value[begin .. end]);
HashMap
基本使用和键列表 + 值列表:
use std::collections::HashMap;
fn main() {
let mut mapper: HashMap<String, i32> = HashMap::new();
mapper.insert(String::from("刘"), 23);
mapper.insert(String::from("张"), 52);
mapper.insert(String::from("李"), 52);
let key = vec!["张三", "李四", "王五"];
let value = vec![241, 1221, 123];
let mapper_new : HashMap<_, _>= key.iter().zip(value.iter()).collect();
print!("{:?}", mapper_new)
}
insert 是用来指定 k 的 v 值
- 如果 k 存在使用 insert 插覆盖旧的 v,得到新的 v
- 如果 k 不存在添加一个 kv 对到 hashmap
如果你想实现的是当某个值不存在的时候我才设置
假设 mapper_new : {"王五":24}
mapper_new.entry(String::from("王五")).or_insert(0);
这个也有一个返回值就是王五存在的时候获取他的 v 也就是 24
这是所有代码
use std::collections::HashMap;
fn main() {
let mut mapper: HashMap<String, i32> = HashMap::new();
mapper.insert(String::from("刘"), 23);
mapper.insert(String::from("张"), 52);
mapper.insert(String::from("李"), 52);
/// 键值对列表合并
let key = vec!["张三".to_string(), "李四".to_string(), "王五".to_string()];
let value = vec![241, 1221, 123];
let mut mapper_new: HashMap<_, _> = key.iter().zip(value.iter()).collect();
print!("{:?}", mapper_new);
// 已经存在 - 暴力插入 管他在不在都插入
let tmp = &String::from("李四");
mapper_new.insert(tmp, &23); // 覆盖了之前的值
print!("{:?}", mapper_new);
// 非暴力插入 只有不存在才插入
// entry -> 表示键是否存在
let mut value = mapper_new.entry(tmp).or_insert(&24);
// 如果不存在 值为24 如果存在返回给value变量
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于