Rust 2021如何实现可接收u16、usize及无约束小正整数字面量的函数
存在可行方案,不需要unsafe、无额外运行时开销,也不需要用户导入trait、使用宏或给字面量加类型约束。
实现思路
- 用密封trait(Sealed Trait)限定可接受的参数类型,避免外部为无关类型实现该trait,同时通过
impl Trait语法隐藏内部trait,用户无需手动导入即可调用。 - 为
u16、usize直接实现零成本转换逻辑,无额外运行时开销。 - 为无约束字面量默认推断的
i32类型实现转换逻辑,添加编译期非负校验,非法值直接在编译阶段报错,转换逻辑强制内联无运行时开销。
完整实现代码
mod sealed { pub trait UsuParam { fn into_usize(self) -> usize; } impl UsuParam for u16 { #[inline(always)] fn into_usize(self) -> usize { self as usize } } impl UsuParam for usize { #[inline(always)] fn into_usize(self) -> usize { self } } impl UsuParam for i32 { #[inline(always)] fn into_usize(self) -> usize { // 编译期校验传入的i32值非负,传入负数直接编译报错 const { assert!(self >= 0, "usu仅接受非负整数参数") }; self as usize } } } // 对外暴露的usu函数,直接调用即可 pub fn usu(u: impl sealed::UsuParam) { let val = u.into_usize(); // 此处添加业务逻辑,val已经是转换完成的usize类型 }
调用验证
你列出的所有调用方式均可正常编译运行:
usu(1 as usize); // 1 usu([1,2].len()); // 2 usu(3u16); // 3 let u16_val = 4u16; usu(u16_val); // 4 usu(5); // 5
内容的提问来源于stack exchange,提问作者Denys Séguret
相关产品推荐
相关产品推荐

