fn t(x: &mut u8) -> &mut u8 {
x
}
fn main() {
let mut x = 5u8;
let y = & mut x;
let z = t(y);
println!("{}", y);
}
编译这个会给我这个错误:
main.rs:9:20: 9:21 error: cannot borrow `y` as immutable because `*y` is also borrowed as mutable
main.rs:9 println!("{}", y);
我原以为y
会在致电t
然后又回到z
时被移动,从而产生error: use of moved value
答案 0 :(得分:3)
您正在从函数返回对参数的可变引用。但是,Rust并不知道方法没有保留该指针的副本没有返回该指针的子部分,如果它是一个结构。这意味着在任何时候,指向的值都可能会改变,这在Rust中是一个很大的禁忌;如果它被允许,那么你很容易导致内存错误。
Rust会自动创建新借用
是的,Rust"重新借用"引用。
一个更好的例子需要更复杂的微笑:
struct Thing { a: u8, b: u8 }
fn t(x: &mut Thing) -> &mut u8 {
&mut x.a
}
fn main() {
let mut x = Thing { a: 5, b: 6 };
let z = t(&mut x);
*z = 0;
// x.a = 0; // cannot assign to `x.a` because it is borrowed
}
这里,t
返回一个指向struct子集的可变指针。这意味着整个结构被借用了,我们无法改变它(除了通过z
)。 Rust将此逻辑应用于所有函数,并且不会尝试识别您的t
函数只返回相同的指针。
答案 1 :(得分:0)
通过使用rustc --pretty=expanded
编译程序,我们可以看到println!
宏借用了它的参数:
#![no_std]
#[macro_use]
extern crate "std" as std;
#[prelude_import]
use std::prelude::v1::*;
fn t(x: &mut u8) -> &mut u8 { x }
fn main() {
let mut x = 5u8;
let y = &mut x;
let z = t(y);
::std::io::stdio::println_args(::std::fmt::Arguments::new({
#[inline]
#[allow(dead_code)]
static __STATIC_FMTSTR:
&'static [&'static str]
=
&[""];
__STATIC_FMTSTR
},
&match (&y,) { // <----- y is borrowed here
(__arg0,)
=>
[::std::fmt::argument(::std::fmt::String::fmt,
__arg0)],
}));
}