[英]Why do I get the error “trait bound FromStr is not satisfied” because of a missing type annotation?
我遇到了一個編譯錯誤,似乎突出顯示了我對類型系統不了解的內容。
如果字符串不是有效的 integer,我想將字符串轉換為 integer,並帶有自定義緊急消息。 我對parse()
返回的Result
進行match
:
fn main() {
let x = match "23".parse() {
Ok(int) => int,
Err(_) => panic!("Not an integer!"),
};
println!("x plus 1 is {}", x+1);
}
(如果這真的是我在我的程序中所做的一切,我只會使用expect()
,但在真正的程序中還有更多。)
我希望 output 24
編譯和運行時。 相反,會出現以下編譯器錯誤:
error[E0277]: the trait bound `(): std::str::FromStr` is not satisfied
--> main.rs:2:24
|
2 | let x = match "23".parse() {
| ^^^^^ the trait `std::str::FromStr` is not implemented for `()`
問題似乎是 Rust 不知道我要解析的類型,這可能是一個問題。 如果我將第 2 行更改為以下內容,錯誤就會消失:
let x: i32 = match "23".parse() {
為什么我收到此錯誤消息,而不是指示需要類型注釋? 該消息似乎在抱怨錯誤 arm 沒有返回任何內容(或者更准確地說,它返回的內容 - 即什么都沒有 - 沒有實現FromStr
特征),但對我來說沒有任何意義,之后呼喚panic!
,匹配的 arm 的 output 的類型可能會產生任何影響——該程序可能會展開堆棧並在該點立即終止,因此類型安全似乎無關緊要!
一個提示是 if 而不是調用panic!
,我只是返回一個 integer (例如, Err(_) => 0
),代碼編譯良好(並按預期工作)。 在這種情況下,Rust 似乎第一次正確地推斷出類型為i32
並且不會運行導致混淆錯誤的任何代碼路徑。
該消息似乎在抱怨錯誤 arm 沒有返回任何內容(或者更准確地說,它返回的內容 - 即什么都沒有 - 沒有實現
FromStr
特征)。
其實你第一次是對的。 錯誤 arm 永遠不會返回。 panic!
字面上稱為永不類型( !
),它與確實返回的單元類型( ()
)不同,盡管它返回的是“無”。
專業提示:永不返回的函數稱為發散函數。
在調用
panic!
,匹配的 arm 的 output 的類型可能會產生任何影響。
它沒有。 never 類型對類型推斷沒有影響,可以用來代替任何其他類型。 例如,此程序編譯時沒有任何錯誤或警告:
#![allow(unreachable_code)]
fn main() {
let _x: () = panic!();
let _y: i32 = panic!();
let _z: &dyn ToString = panic!();
}
但是,我們使用上面的一堆類型注釋來操作返回類型,而不是任何類型提示,Rust 似乎對返回的表達式默認使用()
!
如您的示例的簡化版本所示:
#![allow(unreachable_code)]
fn main() {
let x = panic!();
x + 5;
}
哪個拋出:
error[E0277]: cannot add `i32` to `()`
--> src/main.rs:15:7
|
15 | x + 5;
| ^ no implementation for `() + i32`
|
= help: the trait `std::ops::Add<i32>` is not implemented for `()`
這似乎是一個合理的選擇,因為空表達式(例如空塊)評估為單元類型。
簡而言之:當您將發散的 function 作為表達式中的最終語句並且不使用任何類型注釋時,Rust 會推斷表達式的返回類型為()
。 這就是為什么您的錯誤 arm 被推斷為 return ()
以及為什么您得到FromStr not implemented for ()
錯誤的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.