[英]What's the difference between var and _var in Rust?
鉴于此:
fn main() {
let variable = [0; 15];
}
Rust 编译器产生这个警告:
= note: #[warn(unused_variables)] on by default
= note: to avoid this warning, consider using `_variable` instead
variable
和_variable
什么_variable
?
不同之处在于前面有一个下划线,这会导致 Rust 编译器允许它不被使用。 它是裸下划线_
的一种命名版本,可用于忽略值。
但是, _name
作用与_
不同。 普通下划线立即删除该值,而_name
作用与任何其他变量一样,并在范围末尾删除该值。
它如何与普通下划线不完全相同的示例:
struct Count(i32);
impl Drop for Count {
fn drop(&mut self) {
println!("dropping count {}", self.0);
}
}
fn main() {
{
let _a = Count(3);
let _ = Count(2);
let _c = Count(1);
}
{
let _a = Count(3);
let _b = Count(2);
let _c = Count(1);
}
}
打印以下内容( 操场):
dropping count 2
dropping count 1
dropping count 3
dropping count 1
dropping count 2
dropping count 3
_variable
和variable
之间的主要区别在于,第一个告诉编译器如果我们不在代码中使用它就不要发出任何警告。 例子:
// src/main.rs
fn main() {
let _x = 1;
let y = 2;
}
编译main.rs
给出:
warning: unused variable: `y`
--> src/main.rs:3:9
|
3 | let y = 2;
| ^ help: if this is intentional, prefix it with an underscore: `_y`
|
= note: `#[warn(unused_variables)]` on by default
更有趣的情况是当我们将_
与_variable
进行比较时。
语法 _x 仍然将值绑定到变量,而 _ 根本不绑定。
考虑示例:
// src/main.rs
fn main() {
let s = Some(String::from("Hello!"));
if let Some(_s) = s {
println!("found a string");
}
println!("{:?}", s);
}
当我们尝试编译main.rs
我们得到错误:
error[E0382]: borrow of moved value: `s`
--> src/main.rs:8:22
|
4 | if let Some(_s) = s {
| -- value moved here
...
8 | println!("{:?}", s);
| ^ value borrowed here after partial move
|
= note: move occurs because value has type `std::string::String`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving `s.0`
|
4 | if let Some(ref _s) = s {
| ^^^
啊哈! 语法 _x 仍然将值绑定到变量,这意味着我们正在将s
的所有权转移到_s
,因此,我们不能再访问变量s
了; 当我们尝试打印s
值时会发生这种情况。
正确的做法是:
// src/main.rs
fn main() {
let s = Some(String::from("Hello!"));
if let Some(_) = s {
println!("found a string");
}
println!("{:?}", s);
}
上面的代码工作得很好。 s
不会被移动到_
,所以我们以后仍然可以访问它。
有时我将_
与迭代器一起使用:
fn main() {
let v = vec![1, 2, 3];
let _ = v
.iter()
.map(|x| {
println!("{}", x);
})
.collect::<Vec<_>>();
}
编译给出结果:
1
2
3
当对上面的可迭代类型进行更复杂的操作时,上面的示例对我来说起到了实用程序的作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.