我正在学习Rust,并发现在变量名称的开头添加一个下划线将使编译器不警告它是否未使用。我想知道为什么这个特性存在,因为未使用的变量是不允许的。
发布于 2018-01-20 22:27:20
我可以看到几个原因:
#[must_use]类型的函数,但在特定情况下,您知道可以安全地忽略该值。可以为此使用_模式(它不是变量绑定,而是它自己的模式,但这可能是下划线前缀约定的来源),但是您可能需要记录为什么忽略该值,或者忽略该值是什么。根据我的经验,这在测试中特别常见。used_underscore_binding lint强制执行的。_,因为_不是变量绑定,并且该值不会像变量绑定那样在封闭块的末尾被删除。发布于 2018-01-21 18:36:46
下面是一些例子,说明为什么要忽略未使用的变量的行为。考虑下面的函数中的_s。
fn add_numbers(f: i32, _s: i32) -> i32 {
f + 1
}_s变量使得它能够保持签名不变,即使我们还没有实现它。如果我们发现我们不需要_s,但是由于我们的库在许多不同的项目中使用,所以我们不想将API更改为我们的函数,这也是可行的。这可能是不好的实践,也可能不是不好的实践,但在_s需要留下来而不做任何事情的情况下,这可能是有用的。我们也可以在这里使用_,但对于变量将来的用途,_s可能有更多的意义。
下一个有用的地方是当一个类型实现了Drop,而您关心这个逻辑发生在哪里。在本例中,您可以看到需要_result变量,以便Drop在结束时发生。
fn main() {
let mut num = 1;
// let _ = try_add_numbers(&mut num); // Drop is called here for _
let _result = try_add_numbers(&mut num); // without the _result we have a warning.
println!("{}", num);
// Drop is called here for the _result
}
// keep the api the same even if an aurgument isn't needed anymore or
// has not been used yet.
fn add_numbers(f: i32, _s: i32) -> i32 {
f + 1
}
// This function returns a result
fn try_add_numbers(i: &mut i32) -> Result<GoodResult, GoodResult> {
if *i > 3 {
return Err(GoodResult(false));
}
*i = add_numbers(*i, 0);
Ok(GoodResult(true))
}
struct GoodResult(bool);
impl Drop for GoodResult {
fn drop(&mut self) {
let &mut GoodResult(result) = self;
if result {
println!("It worked");
} else {
println!("It failed");
}
}
}如果我们使用let _result = try_add_numbers(&mut num);,我们有一个变量,它的作用域一直到main的末尾,然后调用drop。如果我们使用了let _ = try_add_numbers(&mut num);,我们仍然不会收到警告,但是在语句末尾会调用drop。如果我们使用没有let绑定的try_add_numbers(&mut num);,就会收到警告。这个程序的输出确实会根据我们在try_add_numbers函数中使用的内容而改变。
It worked
2或
2
It worked因此,_和_named变量都有用途,需要根据程序的输出来选择它们。在游乐场上播放我的例子,以获得它的感觉。
发布于 2021-01-15 09:14:41
let a是一个值绑定,并且将分配一个堆栈空间来存储它的值。let _a是一种类似于let a的行为。此外,它被标记为intentional,因此如果不使用_a,编译器将不会弹出警告。let _是一种模式,而_是一种不能在其他地方使用的reserved identifier。这不会导致分配堆栈空间,因此=右侧的值将在此语句之后不久释放。下面是一个示例:游乐场
pub struct Node {
value: usize,
}
impl Drop for Node {
fn drop(&mut self) {
println!("drop() {}", self.value);
}
}
pub fn square() {
let a = Node { value: 1 };
let _a = Node { value: 2 };
let _ = Node { value: 3 };
println!("Hello, world!");
}
fn main() {
square();
}产出如下:
drop() 3
Hello, world!
drop() 2
drop() 1您可以阅读这来了解更多信息。
https://stackoverflow.com/questions/48361537
复制相似问题