简体   繁体   English

为什么我会因为缺少类型注释而收到错误“trait bound FromStr is not满足”?

[英]Why do I get the error “trait bound FromStr is not satisfied” because of a missing type annotation?

I encountered a compile error that seems to be highlighting something I don't understand about the type system.我遇到了一个编译错误,似乎突出显示了我对类型系统不了解的内容。

I want to convert a string to an integer, with a custom panic message if the string isn't a valid integer.如果字符串不是有效的 integer,我想将字符串转换为 integer,并带有自定义紧急消息。 I do a match on the Result that's returned by parse() :我对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);
}

(If this were really all I was doing in my program, I would just use expect() , but there's more to it in the real program.) (如果这真的是我在我的程序中所做的一切,我只会使用expect() ,但在真正的程序中还有更多。)

I would expect the output 24 when compiled and run.我希望 output 24编译和运行时。 Instead, the following compiler error appears:相反,会出现以下编译器错误:

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 `()`

The issue seems to be that Rust doesn't know what type I'm trying to parse to, and it makes sense this could be a problem.问题似乎是 Rust 不知道我要解析的类型,这可能是一个问题。 If I change line 2 to the following, the error goes away:如果我将第 2 行更改为以下内容,错误就会消失:

    let x: i32 = match "23".parse() {

Why did I get this error message, instead of one indicating that a type annotation was required?为什么我收到错误消息,而不是指示需要类型注释? The message appears to be complaining that the error arm does not return anything (or more precisely, that what it returns -- namely nothing -- doesn't implement the FromStr trait), but it does not make any sense to me that, after calling panic!该消息似乎在抱怨错误 arm 没有返回任何内容(或者更准确地说,它返回的内容 - 即什么都没有 - 没有实现FromStr特征),但对我来说没有任何意义,之后呼唤panic! , the type of the output of that arm of the match could have any effect whatsoever -- the program is presumably going to unwind the stack and terminate immediately at that point, so type safety would seem irrelevant! ,匹配的 arm 的 output 的类型可能会产生任何影响——该程序可能会展开堆栈并在该点立即终止,因此类型安全似乎无关紧要!

One hint is that if instead of calling panic!一个提示是 if 而不是调用panic! , I simply return an integer (eg, Err(_) => 0 ), the code compiles fine (and works as expected). ,我只是返回一个 integer (例如, Err(_) => 0 ),代码编译良好(并按预期工作)。 It seems that in this case, Rust correctly infers the type to be i32 the first time around and doesn't run down whatever code path is leading to the confusing error.在这种情况下,Rust 似乎第一次正确地推断出类型为i32并且不会运行导致混淆错误的任何代码路径。

The message appears to be complaining that the error arm does not return anything (or more precisely, that what it returns -- namely nothing -- doesn't implement the FromStr trait).该消息似乎在抱怨错误 arm 没有返回任何内容(或者更准确地说,它返回的内容 - 即什么都没有 - 没有实现FromStr特征)。

Actually you were right the first time.其实你第一次是对的。 The error arm never returns.错误 arm 永远不会返回。 The return type of panic! panic! is literally called the never type ( ! ) and it's different from the unit type ( () ) which does return, although what it returns is "nothing".字面上称为永不类型! ),它与确实返回的单元类型() )不同,尽管它返回的是“无”。

Pro-tip: functions which never return are called divergent functions.专业提示:永不返回的函数称为发散函数。

it doesn't make any sense to me that, after calling panic!在调用panic! , the type of the output of that arm of the match could have any effect whatsoever. ,匹配的 arm 的 output 的类型可能会产生任何影响。

It doesn't.它没有。 The never type has no influence on type inference and can be used in place of any other type. never 类型对类型推断没有影响,可以用来代替任何其他类型。 For example, this program compiles without any errors or warnings:例如,此程序编译时没有任何错误或警告:

#![allow(unreachable_code)]

fn main() {
    let _x: () = panic!();
    let _y: i32 = panic!();
    let _z: &dyn ToString = panic!();
}

However, we're using a bunch of type annotations above to manipulate the return type, in lieu of any type hints whatsoever Rust seems to settle on the default of () for expressions that return !但是,我们使用上面的一堆类型注释来操作返回类型,而不是任何类型提示,Rust 似乎对返回的表达式默认使用() ! as shown by this simplified version of your example:如您的示例的简化版本所示:

#![allow(unreachable_code)]

fn main() {
    let x = panic!();
    x + 5;
}

Which throws:哪个抛出:

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 `()`

This seems like a reasonable choice given that empty expressions, such as an empty block, evaluate to the unit type.这似乎是一个合理的选择,因为空表达式(例如空块)评估为单元类型。

In short: when you put a divergent function as the final statement in an expression and don't use any type annotations Rust infers the expression's return type to be () .简而言之:当您将发散的 function 作为表达式中的最终语句并且不使用任何类型注释时,Rust 会推断表达式的返回类型为() This is why your error arm is inferred to return () and why you get the FromStr not implemented for () error.这就是为什么您的错误 arm 被推断为 return ()以及为什么您得到FromStr not implemented for ()错误的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rust 索引特征边界中的类型注释错误 - Rust Type annotation Error in Index trait bounding 为什么会出现错误“方法...类型未定义...”? - Why do I get an error “The method … is undefined for the type…”? . 为什么会出现以下错误? 类型“照片”不可分配给类型“从不” - . WHY DO I GET THE FOLLOWING ERROR? Type 'Photo' is not assignable to type 'never' %type 可以与 Object 类型一起使用吗? 是否有可能因为我在尝试这样做时遇到错误 - Could %type be used with Object type? Is it possible because I am getting error while trying to do so Scala:当我使用“Option”时,为什么会出现类型不匹配错误? - Scala: Why do I get a type mismatch error when I use “Option”? Haskell,即使我的类型未指定,我也会收到此错误:无法将类型“a”与“[a]”匹配,“a”是绑定的刚性类型变量 - Haskell, Even though my type is not specified I get this error: Couldn't match type `a' with `[a]', `a' is a rigid type variable bound by 在将字符串解析为数字时,为什么会出现“在此上下文中必须知道此值的类型”的错误? - Why do I get the error “the type of this value must be known in this context” when parsing a string to a number? 具有特征的类型定义:指定显式生命周期界限的差异? - Type definition with a trait: Differences of specifying an explicit lifetime bound? 为什么我会得到一个错误类型,其中的参数被用于同一目的两次 - Why do I get an error type with an argument that is used twice for the same purpose 为什么这种类型的注释错了? - Why is this type annotation wrong?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM