[英]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.