作为参数传递的引用未移动
Reference passed as parameter is not moved
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
- 为什么我会收到这条错误消息?
- 当引用作为函数参数提供时,Rust 是否会自动创建新的借用而不是传递所有权?
- 这种行为的目的是什么?
您正在 return 对函数中的参数进行可变引用。但是,Rust 不知道方法 没有保留该指针的副本 没有 return 该指针的一个子部分,如果它是一个结构。这意味着在任何时候,指向的值都可能被更改,这在 Rust 中是一个很大的禁忌;如果允许,则很容易导致内存错误。
Does Rust automatically create a new borrow
是的,Rust "re-borrows" 参考文献。
一个更好的例子需要稍微复杂一些:
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
return 是指向结构子集的可变指针。这意味着整个结构都是借用的,我们无法更改它(除了通过 z
)。 Rust 将此逻辑应用于所有函数,并且不会尝试识别您的 t
函数只是 return 相同的指针。
通过使用 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)],
}));
}
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
- 为什么我会收到这条错误消息?
- 当引用作为函数参数提供时,Rust 是否会自动创建新的借用而不是传递所有权?
- 这种行为的目的是什么?
您正在 return 对函数中的参数进行可变引用。但是,Rust 不知道方法 没有保留该指针的副本 没有 return 该指针的一个子部分,如果它是一个结构。这意味着在任何时候,指向的值都可能被更改,这在 Rust 中是一个很大的禁忌;如果允许,则很容易导致内存错误。
Does Rust automatically create a new borrow
是的,Rust "re-borrows" 参考文献。
一个更好的例子需要稍微复杂一些:
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
return 是指向结构子集的可变指针。这意味着整个结构都是借用的,我们无法更改它(除了通过 z
)。 Rust 将此逻辑应用于所有函数,并且不会尝试识别您的 t
函数只是 return 相同的指针。
通过使用 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)],
}));
}