我正在尝试编写一个泛型函数,它会尝试将字符串转换为数字类型,如i32
,f64
等。如果字符串不可转换,那么它将返回{{1} }。我正在寻找一个适合在我的通用函数中使用的特性:
0
我发现Rust有一个use std::str::FromStr;
fn get_num_from_str<T: FromStr>(maybe_num_str: &String) -> T {
let maybe_num = T::from_str(maybe_num_str.as_str());
if maybe_num.is_ok() {
return maybe_num.unwrap();
}
0 as T
}
fn main() {
let num_str = String::from("12");
println!("Converted to i32: {}", get_num_from_str::<i32>(&num_str));
}
特征,之前被删除了。现在还有别的东西可以用吗?
我找到了一个解决方法:
Primitive
正如特性限制所暗示的那样,这应该适用于任何具有use std::str::FromStr;
fn get_num_from_str<T: Default + FromStr>(maybe_num_str: &String) -> T {
let maybe_num = T::from_str(maybe_num_str.as_str());
maybe_num.unwrap_or(Default::default())
}
和Default
实现的东西,我应该重命名该函数以反映这一点,但是知道是否仍然很好只有原始数字类型有任何特征,我可以使用它来确保此函数不能用于数字类型以外的任何其他类型。
答案 0 :(得分:9)
num crate中定义的Num
特征应该满足您的需求,但您在Rust中尝试做的并不是惯用的,所以我想提出两点建议:
相反,如果您的函数由于多个原因而无法返回结果,请考虑使用Result<T, E>
类型,如果您的函数可能无法使用Option<T>
类型,则考虑使用Result<T, E>
类型返回结果。
在您的情况下,您可能希望使用Result
,以便您的函数可以通知转换失败的原因 - 字符串是否包含无效的数字字符?请求的类型的值是否超出范围?您的职能的来电者可能需要知道能够最好地处理这种情况。
std::string::String::parse()
或str::parse()
方法的形式包含您要查找的功能(通过通用实现将字符串转换为值)。出于上述原因,这些方法确实返回type Result<T> = std::result::Result<T, Box<std::error::Error>>;
fn main() -> Result<()> {
let num_str = String::from("12");
println!("Converted to i32: {}", num_str.parse::<i32>()?);
Ok(())
}
。通过以上两条信息,您的代码现在可以更加健壮地重写如下(使用Rust 1.26+来简化错误处理):
type Result<T> = std::result::Result<T, Box<std::error::Error>>;
fn main() -> Result<()> {
let num_str = "-1";
println!("Invalid u32 conversion: {}", num_str.parse::<u32>()?);
Ok(())
}
如果出现问题,请注意报告的错误情况:
Error: ParseIntError { kind: InvalidDigit }
这会将std::libc::EXIT_FAILURE
打印到控制台并将值<div class="row inview dragula clearfix">
<div class="col-md-12 clearfix">
<div class="box clearfix" style = "height:243px;border:4px dashed rgba(25,25,25,.5)">
<div class="box-body draggable handle">
Set Up
</div>
</div>
</div>
<div class="col-md-3 clearfix">
<div class="box " style = "height:243px;border:4px dashed rgba(25,25,25,.5)">
<div class="box-body draggable handle">
Shortcut
</div>
</div>
</div>
<div class="col-md-3 clearfix">
<div class="box" style = "height:243px;border:4px dashed rgba(25,25,25,.5)">
<div class="box-body draggable handle">
Shortcut 2
</div>
</div>
</div>
<div class="col-md-9 ">
<div class="box" style = "height:500px;border:4px dashed rgba(25,25,25,.5)">
<div class="box-body draggable handle">
Calendar
</div>
</div>
</div>
<div class="col-md-6 clearfix">
<div class="box " style = "height:243px;border:4px dashed rgba(25,25,25,.5)">
<div class="box-body draggable handle">
Report
</div>
</div>
</div>
</div>
返回给调用进程(表示程序退出并显示错误),所有这些都没有任何值重载或&#34;幻数&#34;必需的。
答案 1 :(得分:6)
不,没有这样的特质。为什么?因为Rust不需要关心区分&#34;原语&#34;来自&#34;非基元&#34;和大多数其他语言一样多。实际上,为什么要?
另外,请注意数组和原始指针也是原语;你真的希望包括那些吗?
我可以用它来确保这个函数不能用于数字类型以外的任何东西。
为什么您希望人为限制您可以使用的类型?为什么您的功能不适用于符合其所需基本标准的任何类型?你是谁试图保护自己?
你的例子可以缩短:
{{1}}