跳转至

数据类型


结构体

所有权

// 定义结构体
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"));