如何在Rust中访问枚举值?

99
struct Point {
    x: f64,
    y: f64,
}

enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point),
}

let my_shape = Shape::Circle(Point { x: 0.0, y: 0.0 }, 10.0);

我想打印出circle的第二个属性,在这里是10.0。 我尝试了my_shape.lastmy_shape.second,但都不起作用。

在这种情况下,我应该怎么做才能打印出10.0?

8个回答

110

如果你只对其中一个变量感兴趣,可以使用if let表达式代替match

struct Point {
    x: f64,
    y: f64,
}

enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point),
}

fn main() {
    let my_shape = Shape::Circle(Point { x: 0.0, y: 0.0 }, 10.0);

    if let Shape::Circle(_, radius) = my_shape {
        println!("value: {}", radius);
    }
}

这意味着“如果my_shape可以解构为一个Circle,则不对第一个索引执行任何操作,但将第二个索引的值绑定到radius”。


65

您可以使用模式匹配:

struct Point {
    x: f64,
    y: f64,
}

enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point),
}

fn main() {
    let my_shape = Shape::Circle(Point { x: 0.0, y: 0.0 }, 10.0);

    match my_shape {
        Shape::Circle(_, value) => println!("value: {}", value),
        _ => println!("Something else"),
    }
}

输出示例:

value: 10

33

这里是另一种方法:

struct Point {
    x: f64,
    y: f64,
}

enum Shape {
    Circle(Point, f64),
}

fn main() {
    let Shape::Circle(_, radius) = Shape::Circle(Point { x: 0.0, y: 0.0 }, 10.0);
    println!("value: {}", radius);
}

只有当模式是不可反驳的,例如当您匹配的枚举类型只有一个变量时,此方法才有效。为使其有效,我必须删除未使用的Rectangle变量。

如果您有多个变量,则通常仍需要完整的匹配表达式,因为您可能正在处理不止一种形状。


不错的尝试,但考虑到他们一开始就有“矩形”,他们很可能会使用它。尽管如此,在与@user1038550和@jcollado的答案相同的方面仍然是有效的。 - Katty T. enby cat.

10

来自Rust编程语言


(以下为要翻译的内容,由于没有提供具体内容,故无法进行翻译)

Another useful feature of match arms is that they can bind to parts of the values that match the pattern. This is how we can extract values out of enum variants.

[...]

fn value_in_cents(coin: Coin) -> u32 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            println!("State quarter from {:?}!", state);
            25
        },
    }
}

如果您想编写能够处理不同类型和表示方式的函数,请查看traits


6

如果只需简单地检索值,可使用 "if let"。

let mut var: f64 = 0.0;
if let Shape::Circle(_, float1) = my_shape {
    var = float1;
}
println!("value is {}", var);

5
let r = match my_shape { Shape::Circle(_, r) => r, _ => 0f64 };

或者
let r = if let Shape::Circle(_, r) = my_shape { r } else { 0f64 };

3

Rust 1.65.0 带来了 let-else,它让您以比 match 或 if-let 更少的嵌套方式以新方式访问单个枚举变量:

fn main() {
    let my_shape = Shape::Circle(Point { x: 0.0, y: 0.0 }, 10.0);

    let Shape::Circle(_, radius) = my_shape else { return; };
    println!("value: {radius}");
}

struct Point {
    x: f64,
    y: f64,
}

enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point),
}

-1
你还可以在枚举上定义一个方法(例如unwrap_radius),然后调用它:
struct Point {
    x: f64,
    y: f64,
}

enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point),
}

impl Shape {
    fn unwrap_radius(self) -> f64 {
        match self {
            Shape::Circle(_, r) => r,
            _ => 0.0,
        }
    }
}

fn main() {
    let my_shape = Shape::Circle(Point { x: 0.0, y: 0.0 }, 10.0);
    println!("{}", my_shape.unwrap_radius());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接