我还看到了其他一些问题,answers指出let _ = foo()
在语句末尾而不是作用域退出处销毁了结果,而let _a = foo()
就是这样做的。 / p>
我找不到对此的任何正式描述,也找不到该语法的任何原理。
我对一些相互关联的东西感兴趣:
答案 0 :(得分:7)
这仅仅是Rust的绑定/解构规则的自然产物吗?
是的。您使用_
来表示您不关心模式中的值,并且一开始就不应该绑定该值。如果值从未绑定到变量,则没有任何要保留的值,因此必须将其删除。
All the Places Patterns Can Be Used:
match
武器if let
表达式while let
条件循环for
循环let
声明在官方文档中甚至没有提及它?
Ignoring an Entire Value with _
请注意,_
不是a valid identifier,因此您不能将其用作名称:
fn main() {
let _ = 42;
println!("{}", _);
}
error: expected expression, found reserved identifier `_`
--> src/main.rs:3:20
|
3 | println!("{}", _);
| ^ expected expression
使用显式作用域实现
我想您可以走这条路线,然后做一些表达式来“徘徊”直到范围结束,但是我看不出任何价值:
let _ = vec![5];
vec![5]; // Equivalent
// Gotta wait for the scope to end to clean these up, or call `drop` explicitly
答案 1 :(得分:5)
使用let _ = foo()
的唯一原因是当函数要求您使用其结果,并且知道您不需要它时。否则,这:
let _ = foo();
与此完全相同:
foo();
例如,假设foo
具有这样的签名:
fn foo() -> Result<String, ()>;
如果不使用结果,将会收到警告,因为Result
具有#[must_use]
attribute。立即进行销毁和忽略结果是一种避免在可能的情况下避免出现此警告的简洁方法,而无需引入可以在整个范围内使用的新变量。
如果您不对结果进行模式匹配,则foo
函数返回后,该值将被删除。不管您明确表示不想要还是不使用它,Rust的行为都一样是合理的。