Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Variables 为什么下划线前缀变量存在?_Variables_Rust_Unused Variables - Fatal编程技术网

Variables 为什么下划线前缀变量存在?

Variables 为什么下划线前缀变量存在?,variables,rust,unused-variables,Variables,Rust,Unused Variables,我正在学习Rust,并发现在变量名的开头添加下划线会使编译器在未使用时不会发出警告。我想知道为什么会有这种特性,因为不用的变量是不受欢迎的 我可以看出几个原因: 您正在调用一个返回#[必须使用]类型的函数,但在您的特定情况下,您知道可以安全地忽略该值。可以使用\uu模式(这不是变量绑定,它本身就是一种模式,但这可能是下划线前缀约定的来源),但是您可能需要记录忽略该值的原因,或者该值是什么。根据我的经验,这在测试中尤其常见 函数参数:您可能必须命名一个参数,因为它是API的一部分,但实际上不需要

我正在学习Rust,并发现在变量名的开头添加下划线会使编译器在未使用时不会发出警告。我想知道为什么会有这种特性,因为不用的变量是不受欢迎的

我可以看出几个原因:

  • 您正在调用一个返回
    #[必须使用]
    类型的函数,但在您的特定情况下,您知道可以安全地忽略该值。可以使用
    \uu
    模式(这不是变量绑定,它本身就是一种模式,但这可能是下划线前缀约定的来源),但是您可能需要记录忽略该值的原因,或者该值是什么。根据我的经验,这在测试中尤其常见
  • 函数参数:您可能必须命名一个参数,因为它是API的一部分,但实际上不需要使用它
  • 宏。在宏中创建的变量以后可以使用,也可以不使用。如果不能在宏调用中使警告静音,那将很烦人。在这种情况下,有一种将下划线加倍的惯例,例如clippy的lint
  • 拉伊。您可能希望为其析构函数的副作用存在一个变量,但不要以其他方式使用它。对于这个用例,不可能简单地使用
    ,因为
    不是变量绑定,并且该值不会像变量绑定一样被丢弃在封闭块的末尾

    • 以下是一些示例,说明为什么您可能希望忽略未使用的变量。在下面的函数中考虑 > s < /C> >

      fn add_numbers(f: i32, _s: i32) -> i32 {
          f + 1
      }
      
      \u s
      变量使签名保持不变,即使我们没有实现它。如果我们发现我们不需要
      \u s
      ,但因为我们的库用于许多不同的项目,所以我们不想将API更改为我们的函数,那么这也行得通。这可能是坏习惯,也可能不是坏习惯,但在
      \u
      需要留下而不做任何事情的情况下,这可能很有用。我们也可以在这里使用
      \u
      ,但是
      \u s
      对于变量将来的用途可能有更多的意义

      下一个有用的地方是当一个类型实现了
      Drop
      并且您关心该逻辑发生在哪里时。在本例中,您可以看到需要
      \u 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");
              }
          }
      }
      

      2
      它起作用了
      

      因此,
      \u
      \u命名的
      变量都有用途,需要根据程序的输出进行选择。在游戏中玩转我的例子,感受一下它

      我在谷歌上查找与匹配变量相关的警告时无意中发现了这一点。这是切相关的

      有时,您可能有代码,其中您获得了一个
      结果
      ,并希望在案例中进行匹配,但您不关心错误值。实际上,您可以使用显式不绑定的
      \uu
      来代替使用
      \ue
      或其他东西。这里有一个具体的例子。我们不关心错误的值,因为我们返回自己的错误

      fn某些方法()->结果{
      // ...
      让id:u32=匹配某些\u str.parse(){
      正常(值)=>值,
      Err()=>返回Err(MyCustomError::Blah)
      };
      // ...
      }
      
      • 让a
        是一个值绑定,将分配一个堆栈空间来存储它的值
      • let a
        是一种行为类似于
        let a
        的东西。此外,它被标记为
        故意的
        ,这样编译器在未使用
        \u a
        时不会弹出警告
      • let
        是一种模式,
        是一种
        保留标识符
        ,不能在其他地方使用。这不会导致分配堆栈空间,因此
        =
        右侧的值将在该语句之后不久释放
      以下是一个例子:

      pub结构节点{
      值:usize,
      }
      节点的impl Drop{
      fn下降(&mut自我){
      println!(“drop(){}”,self.value);
      }
      }
      新界广场酒店{
      设a=Node{value:1};
      设_a=节点{value:2};
      设u=Node{value:3};
      println!(“你好,世界!”);
      }
      fn main(){
      正方形();
      }
      
      输出为:

      drop() 3
      Hello, world!
      drop() 2
      drop() 1
      

      您可以阅读以了解更多信息

      可以使用u模式,使和让foo=具有稍微不同的行为。两者都会停止警告,但是
      let
      会导致返回值
      Drop
      ed出现在语句的末尾,而不是作用域的末尾,因为没有绑定来保存它。接下来的单词字面意思是“这不是变量绑定”。但为了澄清,我在“RAII”点上加了这句话。我想大多数初学者都无法知道模式和绑定具有不同的删除行为,所以我真的不知道您在引用时是否是这么说的。@loganfsmyth我想这不是真的,请参见:。虽然赋值给下划线变量,但该值不会被删除。@J.Doe我没有看视频,但是什么loganfsmyth是绝对正确的。我认为在
      删除
      的情况下,手动调用
      删除
      比使用
      \u结果
      隐藏
      \u结果
      实际用于某件事更有意义。如果在需要的地方调用
      drop
      ,则会使用该值,并且仍然很明显需要将其删除到某个地方。也许这就是灵感所在。问题是“你为什么要使用
      \u e
      ”。上面写着“实际上,你可以用
      来代替。”这是怎么回答这个问题的呢?@mcarton不久前在一个玩具项目上学习生锈时写下了这个答案。不记得了