我是 Rust 的新手,所以我在官方 Guide 中看到了这段代码
let input = io::stdin().read_line()
.ok()
.expect("Failed to read line");
let input_num: Option<uint> = from_str(input.as_slice());
let num = match input_num {
Some(num) => num,
None => {
println!("Please input a number!");
return;
}
};
虽然理解前两个语句(在 input
和 inputnum
上),但我不太确定 match 语句。所以我检查了 documentation这表明 Option<T>
可以取两个值,None
或 Some(T)
对于某些(对象?)T
.所以我测试了下面的代码:
io::println(
match input_num {
Some(num) => "somenum",
None => {
println!("Please input a number only!");
return;
}
}
);
此代码按预期工作;它打印 somenum
如果您输入一个数字,否则它会打印错误消息。但是,编译器会发出警告:warning: unused variable:
编号 , #[warn(unused_variable)] on by default
.这证实了我的怀疑 num
`match 内部用作变量。
问题: rust
怎么可能不会提示(在指南的示例中)有两个同名的变量 num
?或者它是否将指针“移交”到内部 num
到外面num
?
同样在空的情况下 return
究竟返回了什么?我猜是单位 ()
因为提到了here那个
functions without a
-> ...
implicitly have return type()
编辑:很抱歉遗漏了明显的要点。 return
直接退出函数而不用将任何东西放入num
.
附言我注意到使用 cargo build
第二次编译不会发出警告(不进行任何更改)。是否cargo
继续跟踪版本之类的?
最佳答案
您有使用 Java 或 C# 的经验吗?许多主流编程语言允许您shadow在新的 block 作用域中具有另一个同名变量的变量。例如,看看这段 C# 代码:
using System;
public class Test
{
public static void Main()
{
int x = 10;
{
int x = 20;
Console.WriteLine(x);
}
Console.WriteLine(x);
}
}
事实上,Rust 在隐藏方面更加灵活:您可以根据需要多次隐藏变量,而无需显式制作大括号 block 。
fn main() {
let i = 10i32;
let i = "foo";
println!("{}", i);
}
这里,第一个i
和第二个i
没有关系。我们只是失去了一种使用(引用)第一个 i
的方法。
This confirmed my suspicions that the num inside the `match is used as a variable.
是的,模式匹配可以引入新的变量。但是模式匹配引入的新变量 num
与外部 num
没有直接关系,其值由 match
表达式给出。
我可以将您的 Rust 代码翻译成不那么惯用的 Rust 来说明发生了什么:
let num =
if input_num.is_some() {
let num = input_num.unwrap();
num
} else {
println!("Please input a number!");
return;
}
;
至于没有观察到来自 cargo build
的警告,我怀疑是因为 Cargo 已经从你的代码中构建了 .o
而没有重复同样的工作两次,知道您的代码没有变化。
关于rust - Rust 中 Some(T) 中的同名变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26042900/