为什么在可变变量上调用方法会导致其值被移动?
Why does calling a method on a mutable variable cause its value to be moved?
我正在使用 http::Request::builder()
创建请求并使用 uri()
设置请求 uri。
以下代码编译没有问题:
fn get_oauth_token() {
let mut request = Request::builder().uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
但是,如果我先声明变量 request
并对该变量调用 uri()
方法,我会得到如下所示的错误:
fn get_oauth_token() {
let mut request = Request::builder();
request.uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
error[E0382]: borrow of moved value: `request`
--> src\main.rs:9:21
|
7 | let mut request = Request::builder();
| ----------- move occurs because `request` has type `http::request::Builder`, which does not implement the `Copy` trait
8 | request.uri(&*OAUTH_URL);
| ------- value moved here
9 | let uri = match request.uri_ref() {
| ^^^^^^^ value borrowed here after move
请注意,这两个片段之间的唯一区别是我将行 let mut request = Request::builder().uri(&*OAUTH_URL);
拆分为 let mut request = Request::builder();
和 request.uri(&*OAUTH_URL);
.
变量 OAUTH_URL
是这样声明的(我正在使用 dotenv 从 .env 文件加载它):
lazy_static! {
static ref OAUTH_URL: String = env::var("OAUTH_URL").unwrap();
}
现在我查看了错误 E0382 的解释,它告诉我,如果将一个变量的值分配给另一个有意义的变量,该变量的值将被移动。但是,我不明白为什么在这种情况下会发生这种情况,因为我只声明了一个变量,然后对该变量调用了一个方法。
为什么当我调用 request.uri(&*OAUTH_URL);
时 request
的值移动了?
根据 documentation,该方法移动对象然后 returns 返回。所以这两个片段非常不同。
第一个片段是正确的方式,因为值在链中移动并存储在 request
中;完全可以接受!在另一个片段中,request.uri(&*OAUTH_URL);
将值移动到方法中,然后将对象扔掉,即您刚刚使用并丢弃了对象。
要使它们相等,您必须写成 request = request.uri(&*OAUTH_URL);
第一个片段(正确):
fn get_oauth_token() {
// Object moves from Request::builder() -> .uri(&*OAUTH_URL) -> request
let mut request = Request::builder().uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
第二个片段(错误):
fn get_oauth_token() {
// Object moves from Request::builder() -> request
let mut request = Request::builder();
// Object moves from request -> .uri(&*OAUTH_URL) -> nowhere
request.uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
备用代码段(正确):
fn get_oauth_token() {
// Object moves from Request::builder() -> request
let mut request = Request::builder();
// Object moves from request -> .uri(&*OAUTH_URL) -> request again
request = request.uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
我正在使用 http::Request::builder()
创建请求并使用 uri()
设置请求 uri。
以下代码编译没有问题:
fn get_oauth_token() {
let mut request = Request::builder().uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
但是,如果我先声明变量 request
并对该变量调用 uri()
方法,我会得到如下所示的错误:
fn get_oauth_token() {
let mut request = Request::builder();
request.uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
error[E0382]: borrow of moved value: `request`
--> src\main.rs:9:21
|
7 | let mut request = Request::builder();
| ----------- move occurs because `request` has type `http::request::Builder`, which does not implement the `Copy` trait
8 | request.uri(&*OAUTH_URL);
| ------- value moved here
9 | let uri = match request.uri_ref() {
| ^^^^^^^ value borrowed here after move
请注意,这两个片段之间的唯一区别是我将行 let mut request = Request::builder().uri(&*OAUTH_URL);
拆分为 let mut request = Request::builder();
和 request.uri(&*OAUTH_URL);
.
变量 OAUTH_URL
是这样声明的(我正在使用 dotenv 从 .env 文件加载它):
lazy_static! {
static ref OAUTH_URL: String = env::var("OAUTH_URL").unwrap();
}
现在我查看了错误 E0382 的解释,它告诉我,如果将一个变量的值分配给另一个有意义的变量,该变量的值将被移动。但是,我不明白为什么在这种情况下会发生这种情况,因为我只声明了一个变量,然后对该变量调用了一个方法。
为什么当我调用 request.uri(&*OAUTH_URL);
时 request
的值移动了?
根据 documentation,该方法移动对象然后 returns 返回。所以这两个片段非常不同。
第一个片段是正确的方式,因为值在链中移动并存储在 request
中;完全可以接受!在另一个片段中,request.uri(&*OAUTH_URL);
将值移动到方法中,然后将对象扔掉,即您刚刚使用并丢弃了对象。
要使它们相等,您必须写成 request = request.uri(&*OAUTH_URL);
第一个片段(正确):
fn get_oauth_token() {
// Object moves from Request::builder() -> .uri(&*OAUTH_URL) -> request
let mut request = Request::builder().uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
第二个片段(错误):
fn get_oauth_token() {
// Object moves from Request::builder() -> request
let mut request = Request::builder();
// Object moves from request -> .uri(&*OAUTH_URL) -> nowhere
request.uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}
备用代码段(正确):
fn get_oauth_token() {
// Object moves from Request::builder() -> request
let mut request = Request::builder();
// Object moves from request -> .uri(&*OAUTH_URL) -> request again
request = request.uri(&*OAUTH_URL);
let uri = match request.uri_ref() {
Some(uri) => uri.to_string(),
None => String::from(""),
};
println!("{}", uri)
}