如何在Rust中使用From trait实现双向类型转换?
实现私有元组结构体与i32的双向转换
要解决这个双向转换的问题,关键是要为两个方向分别实现From trait——Rust标准库会自动为From提供对应的Into实现,这样你就能灵活使用from()和into()两种转换方式了。
完整可行的实现代码
#[derive(Default)] struct Foo(i32); // 成员设为私有 // 实现从i32到Foo的转换 impl From<i32> for Foo { fn from(n: i32) -> Foo { Foo(n) } } // 实现从Foo到i32的转换 impl From<Foo> for i32 { fn from(foo: Foo) -> i32 { foo.0 // 因为这个impl和Foo在同一模块,所以能访问私有成员 } } fn main() { // Foo转i32的两种方式都能正常工作 let foo = Foo::default(); let num1: i32 = foo.into(); let num2: i32 = i32::from(Foo(456)); // i32转Foo的两种方式也都正常 let goo1 = Foo::from(123); let goo2: Foo = 789.into(); }
为什么之前的代码会报错?
你之前只实现了From<i32> for Foo,这只能支持i32转Foo的场景(比如Foo::from(123)或者123.into())。但Foo转i32需要对应的From<Foo> for i32实现——因为into()方法的底层逻辑是:如果目标类型U实现了From<T>,那么T就自动获得Into<U>的实现。所以要让foo.into()生效,必须让i32能从Foo转换而来,也就是实现From<Foo> for i32。
可选替代方案
如果你不想实现From<Foo> for i32,也可以直接为Foo实现Into<i32> trait,效果是一样的,但推荐优先用From,因为它能自动生成对应的Into实现,减少重复代码:
impl Into<i32> for Foo { fn into(self) -> i32 { self.0 } }
内容的提问来源于stack exchange,提问作者rodrigocfd
相关产品推荐
相关产品推荐

