借用字符串仅在“匹配”块之外有效
Borrowing string works only outside of `match` block
我是 Rust 的新手,我目前遇到借用检查器的问题。此代码无法编译:
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut out = String::new();
let mut xs = self.xs.iter();
for x in 0..11 {
out += match x {
3 | 7 => "|",
_ => &xs.next().unwrap().to_string(),
};
}
write!(f, "{}", out)
}
我收到错误
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:32:23
|
30 | out += match x {
| ____________________-
31 | | 3 | 7 => "|",
32 | | _ => &xs.next().unwrap().to_string(),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
| | creates a temporary which is freed while still in use
33 | | };
| |_____________- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
但是,这段非常相似的代码确实可以编译:(当然,没有我正在寻找的功能)
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut out = String::new();
let mut xs = self.xs.iter();
for x in 0..11 {
out += &xs.next().unwrap().to_string();
}
write!(f, "{}", out)
}
我的问题是,为什么第一个示例不起作用而第二个示例却起作用?我的理解是 match
应该只被评估为它返回的内容,所以在 x
不是 3 或 7 的情况下,它在功能上应该与第二个示例相同。
谢谢!
match
中的手臂可以是带有自己语句的块。其影响是在 match
手臂中创建的临时物品在离开手臂时会掉落。因此,由 xs.next().unwrap().to_string()
创建的临时 String
在 add-assign 可以执行之前被销毁,但 arm 正试图 return 借用临时,导致悬空引用。
你展示的第二个例子没有这个问题,因为它没有使用 match
(或另一个像 if
这样的块构造)所以临时存在直到 在 之后执行 add-assign。
解决此问题的一种方法是让 match
return 的双臂与 String
:
out += match x {
3 | 7 => "|".to_string(),
_ => xs.next().unwrap().to_string(),
};
(如果您需要 match
作为 &str
求值,您可以使用 &match x { ... }
借用结果,但这里没有必要。)
当然,这在3 | 7
的情况下增加了额外的分配,但需要使match
武器的类型保持一致。
考虑在 match
中执行 add-assign。通过这种方法,使手臂类型匹配的问题消失了,临时寿命问题也得到了解决:
match x {
3 | 7 => { out += "|"; }
_ => { out += xs.next().unwrap().to_string(); }
};
我是 Rust 的新手,我目前遇到借用检查器的问题。此代码无法编译:
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut out = String::new();
let mut xs = self.xs.iter();
for x in 0..11 {
out += match x {
3 | 7 => "|",
_ => &xs.next().unwrap().to_string(),
};
}
write!(f, "{}", out)
}
我收到错误
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:32:23
|
30 | out += match x {
| ____________________-
31 | | 3 | 7 => "|",
32 | | _ => &xs.next().unwrap().to_string(),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
| | creates a temporary which is freed while still in use
33 | | };
| |_____________- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
但是,这段非常相似的代码确实可以编译:(当然,没有我正在寻找的功能)
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut out = String::new();
let mut xs = self.xs.iter();
for x in 0..11 {
out += &xs.next().unwrap().to_string();
}
write!(f, "{}", out)
}
我的问题是,为什么第一个示例不起作用而第二个示例却起作用?我的理解是 match
应该只被评估为它返回的内容,所以在 x
不是 3 或 7 的情况下,它在功能上应该与第二个示例相同。
谢谢!
match
中的手臂可以是带有自己语句的块。其影响是在 match
手臂中创建的临时物品在离开手臂时会掉落。因此,由 xs.next().unwrap().to_string()
创建的临时 String
在 add-assign 可以执行之前被销毁,但 arm 正试图 return 借用临时,导致悬空引用。
你展示的第二个例子没有这个问题,因为它没有使用 match
(或另一个像 if
这样的块构造)所以临时存在直到 在 之后执行 add-assign。
解决此问题的一种方法是让 match
return 的双臂与 String
:
out += match x {
3 | 7 => "|".to_string(),
_ => xs.next().unwrap().to_string(),
};
(如果您需要 match
作为 &str
求值,您可以使用 &match x { ... }
借用结果,但这里没有必要。)
当然,这在3 | 7
的情况下增加了额外的分配,但需要使match
武器的类型保持一致。
考虑在 match
中执行 add-assign。通过这种方法,使手臂类型匹配的问题消失了,临时寿命问题也得到了解决:
match x {
3 | 7 => { out += "|"; }
_ => { out += xs.next().unwrap().to_string(); }
};