如何使用From trait实现Rust参数化类型Outer<A>到Outer<B>的转换
问题原因
你编写的实现无法生效的核心原因是和标准库的From全覆盖实现冲突:
标准库为所有类型默认提供了impl<T> From<T> for T的实现,满足任何类型都可以转换为自身。当参数A和B为同一类型时,你编写的impl<A, B: From<A>> From<Outer<A>> for Outer<B>会和标准库的实现出现逻辑重叠,Rust的trait一致性规则不允许这种歧义存在,因此会直接拒绝该实现的编译。
解决方案
方案1:为Outer添加专用转换方法(稳定可用,推荐)
直接给Outer结构体实现自定义转换方法,避开trait实现的冲突限制:
struct Outer<A> { inner: A, } impl<A> Outer<A> { // 只要A可以转换为B,就能调用该方法完成Outer<A>到Outer<B>的转换 fn convert<B: From<A>>(self) -> Outer<B> { Outer { inner: self.inner.into() } } }
使用示例:
let outer_i32 = Outer { inner: 1_i32 }; // 直接调用方法完成类型转换 let outer_i64: Outer<i64> = outer_i32.convert();
方案2:使用nightly版本Rust的特化特性(不稳定,不推荐生产环境使用)
如果可以接受使用nightly工具链,可以开启特化相关特性,标注你的实现优先级低于标准库默认实现来解决冲突:
#![feature(specialization)] struct Outer<A> { inner: A, } impl<A, B: From<A>> From<Outer<A>> for Outer<B> { default fn from(oa: Outer<A>) -> Self { Outer { inner: oa.inner.into(), } } }
该方案的缺点是特化目前仍属于未稳定特性,后续语法和规则可能发生变更。
内容的提问来源于stack exchange,提问作者egerhard
相关产品推荐
相关产品推荐

