rust - 如何避免在 Rust 的代码块内意外地重新声明变量?

标签 rust

我正在学习 Rust,我遇到了这个:

let mut x: i32 = 1;
x = 7;
let x = x; // x is now immutable and is bound to 7

let y = 4;
let y = "I can also be bound to text!"; // y is now of a different type

这怎么可能安全?请检查以下内容:

let temp = 23;

// 200 lines of code

// I'm changing something here <====== IMPORTANT
let temp = 101;

// 200 lines of code

// do something with temp (with 23 not 101 !!!)

如果我再次执行 let temp = 101,我无法知道我刚刚在代码中创建了一个讨厌的错误。我真的需要在键入 let temp 之前搜索 let temp 吗?我错过了什么?

最佳答案

问题不在于 Rust,也不在于任何编程语言,而在于代码。特别是这条“线”:

// 200 lines of code

如果您在声明变量和使用变量之间编写 200(或 400!)行代码,很可能会发生意想不到的事情。但是,如果变量是可变的并且您不小心更改了它,那么无论发生什么情况都可能发生:

let mut a = 1;
a += 1;
// or
let a = 1;
let a = 2;

两者的最终结果相同,但只有一个涉及阴影。

就我个人而言,我发现阴影对于 Rust 的包装器类型(如 OptionResult)非常有用:

fn foo(name: Option<&str>) {
    let name = name.unwrap_or("Who are you");
    println!("{}", name);
}

如果您发现自己无法处理变量阴影,那么我建议您查看 Clippy ,它有多个 shadow_* lints,如果你有任何阴影,你可以打开并禁止你的代码编译。

Sometimes you are changing someone else's code. I have no way to know that a is already being used. How do I pick a variable name then?

我建议您在修改代码之前阅读代码。一些编辑器还允许在文本中搜索模式或突出显示模式。

I'm coming from Java where that's exactly backwards! Meaning, once you declare int x in a scope you can't redeclare it.

没错,但您仍然可以隐藏您的实例或类变量:

public class HelloWorld {
  static int a = 42;

  public static void main(String[] args) {
    int a = 21;
    System.out.print(a); // Oh no, it's not 42 anymore!
  }
}

Java 编译器不会阻止这个错误;这取决于您、您的测试、您的代码审查或外部 linting 工具。

How do you avoid accidentally redeclaring a variable inside a code block in Rust?

您可以在办公 table 旁放一张小纸片。在上面写上数字零。每次声明一个新变量时,都会将数字加一。使用该数字作为所有变量的前缀或后缀。

为了安全起见,您还可以将您的名字添加到变量中 - 您不希望与遵循相同算法的其他任何人发生冲突。您可能还想将函数和类型添加到变量的名称中,以避免不同函数之间的冲突。

当然,这些变量名可能会很长。要解决这个问题,您可能需要缩写以上所有内容,并将数字写为十六进制或 Base64。您可以拥有相当独特的 mtcfjdxBA8293,而不是 my_type_cool_function_john_doe_x_12223123。这不太可能与任何现有变量发生冲突。

(以上为讽刺)


别搞错了:我强烈相信问题是不是变量阴影:它是数百行长的函数,需要大量的脑力消耗。创建函数,在这些类型上创建类型和方法,但在将代码进一步更改为更糟之前以某种方式修复代码。

关于rust - 如何避免在 Rust 的代码块内意外地重新声明变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41051567/

相关文章:

rust - 为什么隐藏不释放借用的引用?

rust - 双冒号在 Rust 中是什么意思?

rust - 如何要求两个特征的关联类型相同?

rust - 如果我指定了正确的 `Fn` 边界,为什么我不能传递通用函数?

rust - Rust 中 Some(T) 中的同名变量

testing - 当 HTTP 服务器在旧服务器关闭后启动时,测试会发生 panic

rust - 调试打印结构时 Rust 中的 dead_code 警告

java - 在 Rust 项目的 C 绑定(bind)上运行 jextract 时, fatal error "' stdlib.h' file not found

android - Android NDK(libgcc_real.a)上 '__aeabi_ul2f'的多个定义

rust - 错误[E0599] : no method named `gen` found for type `&mut G` in the current scope