为什么片段`pattern_matching_2`和`pattern_matching_3`可以工作,而`pattern_matching_1`不能?编译器建议 `let &x = &foo` 移动了字符串 `hello`,我知道这一点,但我不明白问题出在哪里 -- 我根本没有使用 `foo`,而且编译器对于 `pattern_matching_3` 也没有任何抱怨,但它同样移动了字符串 `hello`。
这些示例代码摘自此答案,但并未回答我的问题。
代码片段:
这些示例代码摘自此答案,但并未回答我的问题。
代码片段:
fn pattern_matching_1() {
let foo = String::from("hello");
let &x = &foo;
println!("{}", x);
}
fn pattern_matching_2() {
let foo = 12;
let &x = &foo;
println!("{}", x);
}
fn pattern_matching_3() {
let foo = String::from("hello");
let x = foo;
println!("{}", x);
}
pattern_matching_1
的编译器错误:
error[E0507]: cannot move out of a shared reference
--> src/main.rs:26:14
|
26 | let &x = &foo;
| -- ^^^^
| ||
| |data moved here
| |move occurs because `x` has type `String`, which does not implement the `Copy` trait
| help: consider removing the `&`: `x`
r
对整个函数都是生命周期的,所以我们不能将底层数据移到外面。而在原始例子中,引用只是一个临时的,只在语句的生命周期内存在,因此移动底层数据不会在原始情况下创建任何悬空引用,并且原始代码实际上是安全的(尽管无意义)。 - Sven Marnachr
将成为无效引用。原始帖子中的代码没有这个问题,即使Rust允许在那种情况下移动字符串,我们也不会得到任何无效的引用。(我在这里并不是在纠缠细节 - 我认为这种区别实际上是造成混淆的原因。) - Sven Marnachfoo
)。为什么这是个问题?谢谢。 - Kevin