Rust如何限制泛型T的输入仅为某些指定类型
UPDATE
随着对Rust语言理解的深入,我意识到此前问题中提出的场景和我实际遇到的报错并无关联。
不过原问题标题仍然有效,相关回复仍然具备很高的参考价值,建议大家重点关注标题对应的问题,谢谢。
代码问题梳理
- 语法错误:where从句位置错误,不应该包裹在大括号内,也不应该写在函数体大括号之后
- 逻辑冲突:同时约束了
i32: From<T>又调用了i32::try_from,From是无错转换 trait,TryFrom是可能失败的转换 trait,二者选其一即可满足需求 - 报错根因:调用函数时传入了引用类型,但是现有泛型约束仅针对所有权类型
T,没有覆盖引用场景
方案1:仅允许可无错转换为i32的数字类型
如果输入仅为一定能转换为i32的数字(如u8、i8、u16、i16、i32本身),直接用From约束即可,编译期就会自动拦截非法输入类型:
use std::fmt::Display; fn calculate<T: Display>(input: T) where i32: From<T>, { // --code snip-- let output = i32::from(input); // --code snip-- }
这种写法会自动限制输入为所有符合i32::from()接收规则的类型,字符串、超出i32范围的数字类型(如u32、i64)都会在编译期直接报错,完全符合限制输入为合法数字类型的需求。
方案2:允许可能转换失败的类型,运行时处理错误
如果需要接收范围更大的数字,或者允许字符串类型输入(运行时尝试解析转换),可以把约束替换为TryFrom:
use std::fmt::Display; use std::convert::TryFrom; fn calculate<T: Display>(input: T) -> Result<(), Box<dyn std::error::Error>> where i32: TryFrom<T>, <i32 as TryFrom<T>>::Error: std::error::Error + 'static, { // --code snip-- let output = i32::try_from(input)?; // --code snip-- Ok(()) }
如果需要额外支持字符串转i32的场景,可以将约束调整为T: AsRef<str>,内部调用input.as_ref().parse::<i32>()即可。
i32: From<&_>报错的专项修复
如果需要支持传入引用类型调用(如calculate(&123)),可以给约束添加引用场景适配:
use std::fmt::Display; fn calculate<T: Display>(input: T) where i32: From<T>, for<'a> i32: From<&'a T>, { // 不管传入所有权还是不可变引用都可以正常转换 }
内容的提问来源于stack exchange,提问作者RowSalmon
相关产品推荐
相关产品推荐

