我有一个自定义的枚举类型ValueString
,它包含两个变体:Integer(i64)
和Data(Vec<u8>)
。我已经写了一个名为parse_utf8
的函数,它接受一个泛型类型T
,并试图从newvalue
中解析一个值,返回Option<T>
。
在我的ValueString::new
方法中,我希望能够根据parse_utf8
解析的类型创建ValueString
的不同变体。如果解析的类型是i64,我将创建ValueString::Integer(i)
;否则,我将创建ValueString::Data(newValue)
。
但是,我不明白Rust是如何知道Some(i)
中的类型是i64
的。
pub enum ValueString {
Integer(i64),
Data(Vec<u8>),
}
fn parse_utf8<T: str::FromStr>(newvalue: &[u8]) -> Option<T> {
if let Some(b'0') = newvalue.first() {
None
} else {
str::from_utf8(newvalue).ok().and_then(|s| s.parse().ok())
}
}
impl ValueString {
pub fn new(newValue: Vec<u8>) -> Self {
match parse_utf8(&newValue) {
Some(i) => ValueString::Integer(i),
None => ValueString::Data(newValue),
}
}
}
我试图确定parse_utf8
返回的值的类型,并希望确定它是否是i64
。但是,在尝试创建ValueString
的适当变体时,我遇到了类型不匹配错误。如果解析的类型是i64
,我希望能够创建一个ValueString::Integer(i)
,但我不确定如何执行这种类型检查。
1条答案
按热度按时间rkttyhzu1#
与其他语言不同,Rust编译器可以直观地识别大多数值的类型。这是非常有用的,因为许多类型,比如迭代器链,可能非常复杂,并且必须手动指定它们,就像在旧版本的C++中一样,这是不符合人体工程学的,也是一个很大的麻烦。
编译器知道
parse_utf8
返回Option<T>
。它可以查看Some
变体,该变体必须包含T
。当匹配Some
变量时,T
类型的值i
被插入到ValueString::Integer
中,而ValueString::Integer
必须具有i64
。因此,T
必须是i64
,如果代码是有效的,所以它选择这个值。如果你写了
Some(i) => ValueString::Integer(i as i64)
,那么编译器将无法确定类型是什么,因为有很多内置类型可以转换为i64
,所以你必须直接指定。还有其他情况下,它可能需要帮助,即使它对人类来说是显而易见的,然后您也需要显式指定。