鉴于此:
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
之间的区别是什么?
答案 0 :(得分:6)
区别在于前面的下划线,这导致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);
}
}
打印以下内容(playground):
dropping count 2
dropping count 1
dropping count 3
dropping count 1
dropping count 2
dropping count 3
答案 1 :(得分:1)
_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
进行比较。
Ignoring an Unused Variable by Starting Its Name with _:
语法_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
当上面的示例对可迭代类型执行更复杂的操作时,对我来说是有用的。