struct 和枚举彼此相似.

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

推荐答案

也许解释根本区别的最简单方法是,枚举包含"变体",一次只能有一个变体,而 struct 包含一个或多个字段,其中必须有all个.

因此,您可以使用enum来模拟类似错误代码的东西,在这种情况下,一次只能有一个:

enum ErrorCode {
    NoDataReceived,
    CorruptedData,
    BadResponse,
}

如果需要,枚举变量可以包含值.例如,我们可以将一个 case 添加到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的每个 case 都可以存储在类型为ErrorCode的值中,如下所示(对于不相关的 struct ,这是不可能的).

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"
}

然后,您可以在枚举上 Select match,以确定给定了哪个变量,并根据它是哪个变量执行不同的操作.


相比之下,我上面没有提到的第三种类型的 struct 是最常用的——每个人在简单地说"struct"时都会提到这种类型的 struct .

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
}

Rust相关问答推荐

移植带有可变borrow 的C代码-卸载期间错误(nappgui示例)

把Vector3变成Vector4的绝妙方法

为什么`Vec i64`的和不知道是`Option i64`?

S,一般性状和联想型性状有什么不同?

如何在递归数据 struct 中移动所有权时变异引用?

当对VEC;U8>;使用serde_json时,Base64编码是保护空间的好方法吗?

Pin<;&;mut可能将Uninit<;T>;>;合并为Pin<;&;mut T>;

JSON5中的变量类型(serde)

在复制类型中使用std::ptr::WRITE_VILAR进行内部可变性的安全性(即没有UnSafeCell)

Rust中的位移操作对范围有什么影响?

如何在 Rust 中按 char 对字符串向量进行排序?

std::vector::shrink_to_fit 如何在 Rust 中工作?

rust tokio::spawn 在 mutexguard 之后等待

为什么可以在迭代器引用上调用 into_iter?

为什么1..=100返回一个范围而不是一个整数?

从函数返回 u32 的数组/切片

在 Traits 函数中设置生命周期的问题

返回 &str 但不是 String 时,borrow 时间比预期长

为什么我返回的 impl Trait 的生命周期限制在其输入的生命周期内?

为什么一个整型变量赋值给另一个变量后仍然可以使用?