问题描述
在Result - Rust By Example中有一个示例如下:
1 | use std::num::ParseIntError; |
这里有一个问题没有明确解释: 没有足够的信息, 怎么就确认 parse
返回的 Err
是 ParseIntError
类型了?
拨开迷雾
所幸在下一个章节有这么一句话:
We first need to know what kind of error type we are dealing with. To determine the
Err
type, we look toparse()
, which is implemented with theFromStr
trait fori32
. As a result, theErr
type is specified asParseIntError
.
那我们就顺着这个线索好好梳理一下这个类型是如何确认的.
寻根溯源
parse
方法分析
这里很容易确认 number_str
是一个 str
类型. 那我们需要查找的就是 str.parse
这个方法的文档, 定义如下:
1 | pub fn parse<F>(&self) -> Result<F, <F as FromStr>::Err> |
可以看到 Err
的类型为 <F as FromStr>::Err
. 那我们知道答案一定在 std::str::FromStr下.
不过先别急, 我们看看 parse
的源码:
1 | pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> { |
可以看到非常简单, 我们可以确定这个 Err
就是来自 FromStr::from_str 的返回.
最后让我们再留意一下 number_str.parse::<i32>()
这个用法. 文档中是这样解释的:
As such,
parse
is one of the few times you’ll see the syntax affectionately known as the ‘turbofish’:::<>
. This helps the inference algorithm understand specifically which type you’re trying to parse into.
可以了解到, 如果需要将 str
解析成什么类型, 就在 ::<>
中填写什么类型. 以上文为例, 就是 i32
.
FromStr
分析
让我们仔细阅读一下 std::str::FromStr
这个 method 在文档中的一段描述:
If parsing succeeds, return the value inside
Ok
, otherwise when the string is ill-formatted return an error specific to the inside Err . The error type is specific to implementation of the trait.
重点是The error type is specific to implementation of the trait.
那我们就试着在 Implementors 里找实现对应的实现, 即 impl FromStr for i32
. 那在这个 [implementor]([std::str::FromStr - https://doc.rust-lang.org/std/str/trait.FromStr.html#impl-FromStr-8) 中, 对应的 Err
就很容易找到了:
1 | type Err = ParseIntError |
Conclusion
让我们再简单梳理一下:
首先我们需要匹配 number_str.parse::<i32>()
的结果, 如果是 Err
需要作为 main
函数的结果返回 (main
函数不是重点).
我们从 parse 的返回中找到返回值来自方法 from_str 的调用. 根据其实现方式, 找到 i32
的实现中定义了 Err
的类型: ParseIntError