以下代码是我根据《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
变体的引用
我认为,当我们退出该方法时,这些值将会消失,因此这里会有一个悬空引用
我知道我错了,所以有人可以解释为什么这个代码是有效的吗?
因此,为了简化示例,假设我们将
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
,因此它与函数的返回类型不匹配,无法返回。