Rust 如何保证类型安全?
只是浏览一下(猜谜游戏),我觉得这个代码片段不合适:Rust 如何保证类型安全?,rust,Rust,只是浏览一下(猜谜游戏),我觉得这个代码片段不合适: let num = match input_num { Some(num) => num, None => { println!("Please input a number!"); continue; } }; 在这种情况下,num的类型推断是如何工作的?第一个匹配用例显然返回一个数字,而第二个匹配用例只是println&continue语句,它不返回任何内容(
let num = match input_num {
Some(num) => num,
None => {
println!("Please input a number!");
continue;
}
};
在这种情况下,
num
的类型推断是如何工作的?第一个匹配用例显然返回一个数字,而第二个匹配用例只是println
&continue
语句,它不返回任何内容(或返回()
)。编译器如何假定它是类型安全的?continue
与break
和return
是“发散的”。也就是说,编译器知道控制流不会在它之后恢复,而是转到其他地方。任何返回的函数也是如此代码>;这就是编译器如何知道像std::rt::begin\u unwind
这样的函数永远不会返回的原因。让我们更仔细地看看这段代码:
loop {
// ... some code omitted ...
let num = match input_num {
Some(num) => num,
None => {
println!("Please input a number!");
continue;
}
};
// ... some code omitted ...
}
match语句位于一个循环中,该语言中有几个结构有助于控制循环过程break
提前退出循环,而continue
跳过循环中的其余代码并返回到其开始(重新启动)。因此,上面的匹配基本上可以理解为“检查数字,如果有,则将其分配给num
变量,否则输出消息并从头开始”
“否则”分支的行为很重要:它以控制转移操作结束,在本例中为continue
。编译器看到continue
,知道循环将重新启动。因此,这个分支产生的价值并不重要,因为它永远不会被使用!它还不如什么也不做
这种行为通常使用所谓的模型来建模,它是任何类型的子类型,并且根本没有值。锈菌没有亚型(本质上),所以这种类型非常神奇。它被表示为代码>在类型签名中:
fn always_panic() -> ! {
panic!("oops!")
}
此函数总是死机,这会导致堆栈展开和调用它的线程的最终终止,因此它的返回值(如果有)将永远不会被读取或以其他方式检查,因此完全不返回任何内容是绝对安全的,即使它被用在需要某种具体类型的表达式上下文中:
let value: int = always_panic();
因为总是\u panic()
有返回类型代码>,编译器知道它不会返回任何东西(在这种情况下,因为总是\u panic()
启动堆栈展开),允许它代替任何类型使用是安全的-毕竟,该值即使存在,也永远不会被使用
continue
的工作方式完全相同,但仅限于本地<代码>无
分支“返回”类型
,但是,Some
分支返回某个具体数值类型的值,因此整个match语句都是这种数值类型的,因为编译器知道None
分支将导致控制传输,并且其结果(即使有)将永远不会被使用。我们似乎没有相同的类型安全定义。这里您似乎在谈论类型推断(猜测正确的类型),而类型安全性是一种语言的属性,它阻止您观察给定类型的值,就像它是另一个不相关的类型一样;类型不安全的典型示例是C的void*
。从新手的角度来看,匹配表达式的第一种情况返回“num”(即uint值),而第二种匹配表达式返回“()”(因为,块以“;”)结尾,在我看来,代码混合了两种不同的类型(uint类型和()类型)我理解你的观点,但这并不意味着这不是类型安全的,只要在本例中,编译器将num
的类型记录为uint
或()
,并且只允许相关操作。当然,正如答案中所解释的(但不是你在学习之前可以知道的),它实际上更神奇:)注意,代码>是通常称为底部的文献,请参阅。