[英]Why would you ever use the same lifetimes for references in a struct?
这个问题类似于什么时候在结构中定义多个生命周期有用? ,但希望足够不同。 这个问题的答案很有帮助,但侧重于一种方法的优点(对结构中的引用使用不同的生命周期),而不是缺点(如果有的话)。 像这样的问题,正在寻找关于如何在创建结构时选择生命周期的指导。
将此称为捆绑在一起的版本,因为x和y需要具有相同的生命周期:
struct Foo<'a> {
x: &'a i32,
y: &'a i32,
}
并将其称为松散版本,因为生命周期可能会有所不同:
struct Foo<'a, 'b> {
x: &'a i32,
y: &'b i32,
}
引用问题的答案给出了一个明确的案例,其中客户端代码可以在松散版本的情况下编译/运行,但是对于捆绑在一起的版本将会失败。 是不是所有适用于捆绑版本的客户端代码也适用于松散版本并且保证安全 (即安全)? 正面不是真的。 从结构设计者的角度来看, 松散版本显然更加灵活。 鉴于它是一个好的/可接受的答案,指导可能是 - 当在结构中使用引用时总是给它们不同的生命周期。
这个建议的缺点是什么,忽略了额外的打字? 例如,在结构中要求引用具有相同的生命周期是否有益处?
要求结构中的引用具有相同的生命周期是否有益处
是的,它不仅仅是一个结构。 如果生命周期总是彼此不同,那么你就不能写这个函数:
fn foo<'a, 'b>(a: &'a str, b: &'b str) -> &str {
// What lifetime to return?
if (global_random_number() == 42) {
a
} else {
b
}
}
应用于结构,你可以有这样的东西:
struct EvenOrOdd<'a, 'b> {
even: &'a str,
odd: &'b str,
}
impl<'a, 'b> EvenOrOdd<'a, 'b> {
fn do_it(&self, i: u8) -> &str {
if i % 2 == 0 {
self.even
} else {
self.odd
}
}
}
请注意,虽然这个编译,但它不会返回一个可以比结构本身更长的字符串 ,这不是预期的。 此代码失败,即使它应该能够工作:
fn foo<'a, 'b>(a: &'a str, b: &'b str) {
let result = { EvenOrOdd { even: a, odd: b }.do_it(42) };
println!("{}", result);
}
这将适用于统一的生命周期:
struct EvenOrOdd<'a> {
even: &'a str,
odd: &'a str,
}
impl<'a> EvenOrOdd<'a> {
fn do_it(&self, i: u8) -> &'a str {
if i % 2 == 0 {
self.even
} else {
self.odd
}
}
}
这与链接答案相反,后者的评论如下:
您希望能够获取聚合值并在使用后拆分它的一部分
在这种情况下,我们希望获取一个聚合值并统一它们。
在极少数情况下,您可能需要在不同的和统一的生命周期之间穿针:
struct EvenOrOdd<'a, 'b: 'a> {
even: &'a str,
odd: &'b str,
}
impl<'a, 'b> EvenOrOdd<'a, 'b> {
fn do_it(&self, i: u8) -> &'a str {
if i % 2 == 0 {
self.even
} else {
self.odd
}
}
}
虽然这在需要的时候很有用,但我无法想象如果我们每次都必须这样写的话,会发出嚎叫和咬牙切齿的声音。
无视额外打字
我不会。 有
foo<'a>(Bar<'a>)
肯定比
foo<'a, 'b', 'c, 'd>(Bar<'a, 'b', 'c, 'd>)
当您没有从额外的通用参数中受益时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.