Rust中var和_var的区别是什么?

时间:2017-12-06 00:04:16

标签: 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之间的区别是什么?

2 个答案:

答案 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)

_variablevariable之间的主要区别在于,如果我们不在代码中使用它,第一个告诉编译器不要给出任何警告。示例:

// 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

当上面的示例对可迭代类型执行更复杂的操作时,对我来说是有用的。