我必须立刻押注 Rust 之四🎲:结构体与枚举

167 阅读2分钟

结构体(Structs)

结构体是将多个相关的数据组合在一起的一种方式。结构体中的每个字段都有自己的名称和类型。

结构体定义

struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

使用结构体

fn main() {
    let user1 = User {
        username: String::from("修仙的人"),
        email: String::from("example@example.com"),
        sign_in_count: 1,
        active: true,
    };
​
    println!("Username: {}", user1.username);
}

元组结构体(Tuple Structs)

Rust 还支持元组结构体,它们类似于元组,但带有类型名称:

struct Color(i32, i32, i32);
​
fn main() {
    let black = Color(0, 0, 0);
}

枚举(Enums)

枚举允许你定义一组可能的值,并且每个枚举值可以包含不同类型的数据。

枚举定义

enum IpAddrKind {
    V4(String),
    V6(String),
}

使用枚举

fn main() {
    let home = IpAddrKind::V4(String::from("127.0.0.1"));
    let loopback = IpAddrKind::V6(String::from("::1"));
​
    match home {
        IpAddrKind::V4(addr) => println!("IPv4 address: {}", addr),
        IpAddrKind::V6(addr) => println!("IPv6 address: {}", addr),
    }
}

Option 枚举

Rust 的标准库定义了一个常用的枚举:Option,它表示一个可能有值也可能无值的类型:

let some_number = Some(5);
let absent_number: Option<i32> = None;

Q & A

Q: 枚举中可以在 () 里传入内容,这与 typescript 不太一样,为什么这么设计?

A:

在 TypeScript 中,枚举的值是固定的,通常不会包含额外的数据。

enum Message {
    Quit = "Quit",
    Move = "Move",
    Write = "Write"
}
​
let message = Message.Quit;
console.log(message);  // 输出 "Quit"

在 Rust 中,枚举不仅仅是常量或标签,还可以携带数据。

这使得它在表达复杂的数据结构和控制流时非常强大。

例如,Option<T> 可以表达一个值要么存在、要么不存在;

Result<T, E> 可以表达操作要么成功、要么失败并附带错误信息。

enum Option<T> {
    Some(T),
    None,
}
​
enum Result<T, E> {
    Ok(T),
    Err(E),
}

也可以表达更灵活的数据结构。

例如,一个网络应用的状态机可以通过枚举来表示:

enum ConnectionState {
    Disconnected,
    Connecting(String),
    Connected { 
        ip: String, 
        port: u16 
    },
}

当然,Rust 枚举不一定必须携带数据

enum Direction {
    Up,
    Down,
    Left,
    Right,
}
​
fn move_direction(direction: &Direction) {
    match direction {
        Direction::Up => println!("Moving up!"),
        Direction::Down => println!("Moving down!"),
        Direction::Left => println!("Moving left!"),
        Direction::Right => println!("Moving right!"),
    }
}
​