struct - 我们什么时候应该使用结构而不是枚举?

标签 struct enums rust

结构和枚举彼此相似。

什么时候使用结构而不是枚举更好(反之亦然)?有人可以给出一个明确的例子,说明使用结构比使用枚举更可取吗?

最佳答案

也许解释根本区别的最简单方法是枚举包含“变体”,一次只能有一个,而结构包含一个或多个字段,全部其中你必须拥有。

因此您可以使用 enum 来模拟错误代码之类的东西,一次只能有一个:

enum ErrorCode {
    NoDataReceived,
    CorruptedData,
    BadResponse,
}

如果需要,枚举变体可以包含值。例如,我们可以像这样向 ErrorCode 添加一个案例:

enum ErrorCode {
    NoDataReceived,
    CorruptedData,
    BadResponse,
    BadHTTPCode(u16),
}

在这种情况下,ErrorCode::BadHTTPCode 的实例总是包含一个 u16

这使得每个单独的变体表现得有点像 tuple struct or unit struct :

// Unit structs have no fields
struct UnitStruct;

// Tuple structs contain anonymous values.
struct TupleStruct(u16, &'static str);

但是,将它们写成枚举变体的优点是 ErrorCode 的每个情况都可以存储在 ErrorCode 类型的值中,如下所示(这将不相关的结构是不可能的)。

fn handle_error(error: ErrorCode) {
    match error {
        ErrorCode::NoDataReceived => println!("No data received."),
        ErrorCode::CorruptedData => println!("Data corrupted."),
        ErrorCode::BadResponse => println!("Bad response received from server."),
        ErrorCode::BadHTTPCode(code) => println!("Bad HTTP code received: {}", code)
    };
}

fn main() {
    handle_error(ErrorCode::NoDataReceived); // prints "No data received."
    handle_error(ErrorCode::BadHTTPCode(404)); // prints "Bad HTTP code received: 404"
}

然后您可以在枚举上匹配以确定您得到的变体,并根据它执行不同的操作。


相比之下,我上面没有提到的第三种结构是最常用的——这是每个人在简单地说“结构”时所指的结构类型。

struct Response {
    data: Option<Data>,
    response: HTTPResponse,
    error: String,
}

fn main() {
    let response = Response {
        data: Option::None,
        response: HTTPResponse::BadRequest,
        error: "Bad request".to_owned()
    }
}

请注意,在这种情况下,为了创建一个Response,它的所有字段都必须被赋值。

此外,response 的值的创建方式(即 HTTPResponse::Something)暗示 HTTPResponse 是一个枚举。它可能看起来像这样:

enum HTTPResponse {
    Ok,         // 200
    BadRequest, // 400
    NotFound,   // 404
}

关于struct - 我们什么时候应该使用结构而不是枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48739776/

相关文章:

Rust:如何使用 async-std + TLS + HTTP 代理(http 隧道)?

rust - 处理由 C FFI 强制执行的有问题的父子关系

rust - 在线程之间共享文件句柄

go - 在 Go 中获取子结构字段

c - 将 xml 值映射到结构体值

java - 在 switch case 中使用枚举,但不作为 switch 参数

java - 如何从 Javascript (Java 1.8) 访问 Java 枚举

c# - LinqToDB 如何将枚举存储为字符串值?

C++ 指针设置为地址,但在程序的不同部分莫名其妙地指向不同的值

c++ - Struct 中具有多个标记名称的构造函数 (C++)