我的Rust代码中有这个泛型函数:
fn test<T>(text: &str) -> T {
text.parse::<T>()
}
这个想法是调用者会做类似
的事情test::<u64>("2313");
但编译失败并显示此消息
error: the trait `core::str::FromStr` is not implemented for the type `T` [E0277]
我昨天刚开始学习Rust,所以这可能是一个非常基本的问题,我找不到答案。
答案 0 :(得分:7)
与错误消息状态类似,T
需要实现core::str::FromStr
才能适用于parse
功能。 parse
的类型签名是:
fn parse<F>(&self) -> Result<F, F::Err> where F: FromStr
这限制了F
(或者,在您的情况下为T
)可以用于实施FromStr
的人。您的另一个问题是test
返回的类型;它应该与parse
- Result
。
解决这些问题后,您的功能将起作用:
use std::str::FromStr;
fn test<T: FromStr>(text: &str) -> Result<T, T::Err> {
text.parse::<T>()
}
fn main() {
println!("{:?}", test::<u64>("2313"));
}
确定(2313)
答案 1 :(得分:4)
当您声明泛型类型参数T
时,您对该类型一无所知。它可以是i32
,String
,()
或PinkElephant
;其中只有两个可以从字符串中解析出来。
限制Rust中类型的方法是通过 trait bounds :我们从类型中明确请求特定行为。喜欢&#34;这种类型可以是任何类型,但我至少想要克隆这种类型的一个实例#34; (这将是Clone
特征)。您可以(并且应该!)阅读有关特征in the dedicated chapter in the Rust book主题的更多信息。
那么您对类型T
的期望是什么?您希望使用str::parse()
从字符串创建T
的实例。 parse()
的函数签名是:
fn parse<F>(&self) -> Result<F, F::Err>
where F: FromStr
它还采用此通用参数F
并将其与特征FromStr
绑定。因此,为了使用parse()
,您的类型参数T
也需要实现FromStr
。你的功能可能如下所示:
use std::str::FromStr;
fn test<T: FromStr>(text: &str) -> T {
text.parse::<T>().expect("string was invalid!")
}
你问的expect()
是什么?嗯......我们在这里触及另一个主题:错误处理。还有一个chapter on that topic in the book,您应该阅读。简而言之:您需要以某种方式处理字符串无效的情况(例如,当您尝试解析整数时,如"peter"
)。 expect()
可能是错误的方式:当解析没有成功时,它只是恐慌(中止线程)。
还要记住,有一个编译器错误索引,您可以在其中阅读有关特定错误的更多信息。 Here is the entry代表你的错误E0277。