我正在学习 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 的包装器类型(如 Option
或 Result
)非常有用:
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/