[英]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.