数据类型
结构体
所有权
// 定义结构体
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
struct Color(i32, i32, i32);
struct AlwaysEqual;
// 创建结构体
let user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
// 可变
let mut user1 = User {}
// 结构体更新语法 涉及到了移动
let user2 = User {
email: String::from("another@example.com"),
..user1
};
结构体.字段
获取值
结构体.字段 = 值
赋值
方法
impl 结构体名 {
fn 方法名(&self) -> u32 {
self.width * self.height
}
}
// 使用
结构体对象名.方法()
String
所有权, 集合类型
let 变量名 = String::from("值");
let 变量名 = "值".to_string();
// 创建空的
let mut 变量名 = String::new();
// 替换 并返回一个新的
let name = String类型.replace("C++", "CPP")
let mut s = String::from("Hello");
s.push_str(", world!"); // 追加字符串
s.push('!'); // 追加字符
// 将字符串拼接
let s = format!("{}-{}-{}", s1, s2, s3);
// 处理每一个 Unicode 标量值
for c in "नमस्ते".chars() {
println!("{}", c);
}
for b in "नमस्ते".bytes() {
println!("{}", b);
}
引用
在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。
引用必须总是有效的。
let s1 = String::from("hello");
函数(&s1);
fn 函数(参数名: &String) -> usize {
// 代码块
}
可变引用
同一时间只能有一个可变引用 需要释放后才能继续创建可变引用
不能在拥有不可变引用的同时拥有可变引用
let s1 = String::from("hello");
函数(&mut s);
fn 函数(参数名: &mut String) -> usize {
// 代码块
}
不再使用引用时可以使用可变引用
let mut s = String::from("hello");
let r1 = &s; // 没问题
let r2 = &s; // 没问题
println!("{} and {}", r1, r2);
// 此位置之后 r1 和 r2 不再使用
let r3 = &mut s; // 没问题
println!("{}", r3);
Vec
所有权, 集合类型
单独的数据结构中储存多个值
let v: Vec<i32> = Vec::new();
let mut v = Vec::new();
// 通过初始值来标注类型
let v = vec![1, 2, 3];
&v[2] // 访问
v.get(2) // 访问
v.push(5)
添加元素
&'static
字符串字面量 存在于整个程序的生命周期内
let s: &'static str = "Hello, world!";
map
HashMap
所有权
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10)
插入与更新
scores.entry(键).or_insert(值)
只在键不存在时插入
scores.get()
通过key获取值
// 遍历
for (key, value) in &scores {
println!("{}: {}", key, value);
}
slice
切片
slice
被使用时,原始数据必须保持有效, 无所有权 动态大小 轻量级
let s = String::from("hello world");
let s1 = &s[0..5];
let s2 = &s[6..11];
let s3 = &s[0..5];
let s4 = &s[6..];
let s4 = &s[..];
.len()
大小
.clone()
克隆
&str
函数参数推荐使用, 可以接受 &str 与 String
不拥有字符串数据的所有权
任何字符串数据的引用, 切片
let greeting: &str = "Hello, world!";
整型
类型 | 字节 | 范围 |
---|---|---|
i8 | 1 | -128 到 127 |
i16 | 2 | -32768 到 32767 |
i32 | 4 | -2147483648 到 2147483647 |
i64 | 8 | -9223372036854775808 到 9223372036854775807 |
i128 | 16 | (2的129次方)/2 |
isize | 取决于平台 32 或 64 | |
u8 | 1 | 0 到 255 |
u16 | 2 | 0 到 65535 |
u32 | 4 | 0 到 4294967295 |
u64 | 8 | 0 到 18446744073709551615 |
u128 | 16 | 2的129次方 |
usize | 取决于平台 32 或 64 |
浮点型
默认是f64, f64与f32在现代CPU中性能差距不大(不包括单片机之类)
类型 | 字节 | 范围 |
---|---|---|
f32 | 4 | 大约6位小数 |
f64 | 8 | 大约15位小数 |
Bool
类型 | 字节 |
---|---|
bool | 1 |
char
需要用单引号进行定义
let char_literal = 'a';
类型 | 字节 | 范围 |
---|---|---|
char | 4 |
数组
元素必须相同 固定长度
// 定义
let 名称 = [值, 值, 值];
let mut 名称 = [值, 值, 值];
数组[0]
获取元素
数组[0] = 值
赋值 元素
数组.len()
获取长度
元组
元素可以不同 固定长度
// 定义
let 名称 = (值, 值, 值);
let mut 名称 = (值, 值, 值);
let 名称: (i32, f64, u8) = (500, 6.4, 1);
元组.0
获取元素
元组.0 = 值
赋值 元素
// 大小
元组.len()
枚举
枚举可以定义方法和关联函数impl
enum IpAddrKind {
V4,
V6,
}
let four = IpAddrKind::V4;
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
types(其它枚举),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));