![](/img/trans.png)
[英]Learning how to properly reference to a struct field when using scanf (C)
[英]Are there any restrictions when using a reference in a field of a struct?
我試圖了解 Rust 中的生命周期如何影響結構。 附件是一個讓我困惑的最小例子。
我想給一個 struct 一個對象的引用,然后有必要更改這個對象。 由於借用時無法更改對象,因此我認為必須在更改時刪除引用。 所以我的想法是將變量定義為一個選項,並通過將其設置為None
在修改對象期間刪除引用。 對於不使用 Struct 的示例,這似乎有效。 但是,如果我現在將此引用放入 Struct 中,則它不起作用。 在我看來,借用檢查器忽略了變量string
不再被借用的事實。 有沒有辦法仍然使用結構實現所需的行為?
這有效( 鏈接到操場):
fn main() {
let mut string = "mutable string".to_string();
let mut ref_to_string: Option<&str> = Some(&string);
ref_to_string = None;
string = "mutated string".to_string();
ref_to_string = Some(&string);
}
但是,這不起作用鏈接到操場:
struct Foo<'a> {
pub ref_data: Option<&'a str>,
}
fn main() {
let mut string = "mutable string".to_string();
let mut foo = Foo{ref_data: Some(&string)};
foo.ref_data = None;
string = "mutated string".to_string();
foo.ref_data = Some(&string);
}
錯誤信息:
error[E0506]: cannot assign to `string` because it is borrowed
--> src/main.rs:11:5
|
9 | let mut foo = Foo{ref_data: Some(&string)};
| ------- borrow of `string` occurs here
10 | foo.ref_data = None;
11 | string = "mutated string".to_string();
| ^^^^^^ assignment to borrowed `string` occurs here
12 | foo.ref_data = Some(&string);
| ---------------------------- borrow later used here
For more information about this error, try `rustc --explain E0506`.
問題是您兩次引用string
變量。 當借用第一個時,將&str
生命周期綁定為至少作為foo
活着。 引用位於“另一個”變量中的另一個字符串應該沒有問題:
fn main() {
let string = "mutable string".to_string();
let mut foo = Foo {
ref_data: Some(&string),
};
foo.ref_data = None;
let string = "mutated string".to_string();
foo.ref_data = Some(&string);
}
注意使用另一個let
綁定而不是改變變量。
問題是整個Foo
在一生中都是通用的。 這樣,當您分配foo = Foo {ref_data: Some(&string)}
, foo
的類型是Foo<'lifetime_of_string>
。 您可以foo.ref_data
地將foo.ref_data
設置為None
,但就借用檢查而言,仍然有一個存活對象的生命周期與string
的生命周期重疊。 出於這個原因,只要foo
存在, string
就會被借用。 唯一的方法是刪除整個foo
:
let mut string = "mutable string".to_string();
let mut foo = Foo{ref_data: Some(&string)};
drop(foo);
foo = Foo { ref_data: None };
string = "mutated string".to_string();
foo.ref_data = Some(&string);
秘密在於Foo
結構體的定義:
struct Foo<'a> {
pub ref_data: Option<&'a str>,
}
更具體地說,在'a
生命周期說明符”中。 通過指定Foo
存在於'a
並且ref_data
具有相同的生命周期( &'a str
),你說你的&str
將與Foo
一樣長。 所以只要Foo
還活着,編譯器就不能刪除對string
的引用。
不幸的是,只有在字段為Some
時,才能指定結構體的生命周期為'a
。
要改變結構引用的對象,您可以:
RefCell
)。哪種方法更好取決於您的特定用例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.