返回 Rust 中枚举变体的引用

问题描述 投票:0回答:1

以下代码是我根据《Rust 编程语言》一书第 13 章修改的代码

#[derive(Debug)]
enum ShirtColor {
    Red,
    Blue,
    Yello,
}

struct Inventory {
    shirts: Vec<ShirtColor>,
}

impl<'a> Inventory {
    fn giveaway(&self, user_pref: Option<&'a ShirtColor>) -> &'a ShirtColor {
        user_pref.unwrap_or_else(|| self.most_stocked())
    }

    fn most_stocked(&self) -> &'a ShirtColor {
        let mut red_count = 0;
        let mut blue_count = 0;
        let mut yello_count = 0;

        for color in &self.shirts {
            match color {
                ShirtColor::Red => red_count += 1,
                ShirtColor::Blue => blue_count += 1,
                ShirtColor::Yello => yello_count += 1,
            }
        }

        if red_count > blue_count && red_count > yello_count {
            &ShirtColor::Red
        } else if blue_count > red_count && blue_count > yello_count {
            &ShirtColor::Blue
        } else {
            &ShirtColor::Yello
        }
    }
}

fn main() {
    let store = Inventory {
        shirts: vec![
            ShirtColor::Blue,
            ShirtColor::Red,
            ShirtColor::Blue,
            ShirtColor::Yello,
            ShirtColor::Yello,
            ShirtColor::Yello,
        ],
    };

    let user_pref1 = Some(&ShirtColor::Red);
    let giveaway1 = store.giveaway(user_pref1);
    println!(
        "The user with preference {:?} gets {:?}",
        user_pref1, giveaway1
    );

    let user_pref2 = None;
    let giveaway2 = store.giveaway(user_pref2);
    println!(
        "The user with preference {:?} gets {:?}",
        user_pref2, giveaway2
    );
}

我想知道为什么我可以在

ShirtColor
方法中返回对
most_stocked
变体的引用

我认为,当我们退出该方法时,这些值将会消失,因此这里会有一个悬空引用

我知道我错了,所以有人可以解释为什么这个代码是有效的吗?

rust
1个回答
0
投票

因此,为了简化示例,假设我们将

most_stocked
方法替换为无论如何都只返回红色的
just_red
方法:

fn just_red(&self) -> &'a ShirtColor {
        &ShirtColor::Red
}

之所以有效,是因为它不等于:

fn just_red(&self) -> &'a ShirtColor {
        let red = ShirtColor::Red;
        &red
}

正如您所期望的,由于悬空引用问题而无法编译。

所以基本上这里发生的事情是 Rust 知道

ShirtColor::Red
是一个常量值,所以如果你使用
&
借用它,这个借用具有
'static
生命周期。所以
&ShirtColor::Red
的类型是
&'static ShirtColor
。由于该函数应该返回一个
&'a ShirtColor
,并且
'static
'a
长(
'static
比所有其他生命周期都长),因此
&'static ShirtColor
强制返回为
&'a ShirtColor
。相反,如果我们首先绑定
let red = ShirtColor::Red
,则
&red
的值具有匿名生命周期,当局部变量
red
被删除时,该生命周期在当前函数结束时结束。因此,
&red
的生命周期比
'a
短,因此
&red
无法强制转换为
&'a ShirtColor
,因此它与函数的返回类型不匹配,无法返回。

© www.soinside.com 2019 - 2024. All rights reserved.