gpt4 book ai didi

generics - 有没有一种方法可以实现与泛型相结合的 `as`语义?

转载 作者:行者123 更新时间:2023-12-03 11:45:41 27 4
gpt4 key购买 nike

我正在尝试将通用字符串写入Rust中的数字函数,其中支持的类型为i16i32i64u32u64f32f64
最初我有这个:

fn str_to_num<N>(s: &str, default_res: N) -> N
where
N: FromStr,
{
if let Ok(n) = N::from_str(s) {
return n;
}
default_res
}

在我被要求也支持十六进制字符串之前,这种方法工作得很好。
由于我们只想将十六进制字符串解析为整数,所以我现在有两个版本的函数:
use std::convert::TryFrom;
use std::str::FromStr;

fn str_to_num_with_hex<N>(s: &str, default_res: N) -> N
where
N: FromStr + TryFrom<u64>,
{
if s.starts_with("0x") || s.starts_with("0X") {
if let Ok(n) = u64::from_str_radix(&s[2..], 16) {
if let Ok(n) = N::try_from(n) {
return n;
}
}
}
return str_to_num(s, default_res);
}

fn str_to_num<N>(s: &str, default_res: N) -> N
where
N: FromStr,
{
if let Ok(n) = N::from_str(s) {
return n;
}
default_res
}

但是,当使用适合 u64而不适合 i64的十六进制字符串测试该函数时, TryFromas的行为似乎有所不同。有没有一种方法可以实现将 as语义与泛型结合起来?
fn main() {
let hex = "0xB85991EE5DA2B557";
let unsigned_long: u64 = str_to_num_with_hex(hex, 0);
let signed_long: i64 = str_to_num_with_hex(hex, 0);
println!("{}", unsigned_long); // prints 13283809028865176919
println!("{}", signed_long); // prints 0
println!("{}", unsigned_long as i64); // prints -5162935044844374697
}

最佳答案

我不这么认为。 as字面意义上不会失败,遗憾的是,为了方便起见并与现有语言保持一致,Rust决定实现as来进行可能有损的数字转换,例如isize as u8
try_from实际上可能会失败,这就是重点。因此,如果遇到有损转换(输入超出范围),它将失败,这很重要。

我建议为自己想要的语义创建自己的特征,例如

trait FromHex where Self: Sized {
fn from_hex(s: &str) -> Option<Self>;
}

impl FromHex for u64 {
fn from_hex(s: &str) -> Option<u64> {
u64::from_str_radix(s, 16).ok()
}
}
impl FromHex for i64 {
fn from_hex(s: &str) -> Option<i64> {
u64::from_hex(s).map(|v| v as i64)
}
}

fn main() {
let s = "B85991EE5DA2B557";
println!("{:?} {:?}", u64::from_hex(s), i64::from_hex(s));
}

conv也许也可以开箱即用地完成您想做的事情。

关于generics - 有没有一种方法可以实现与泛型相结合的 `as`语义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61269025/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com