Rust类型转换时,如何无需调用.clone()复用结构体字段?
Rust结构体转换时无需Clone复用已移动字段的解决方案
编译错误信息
error[E0382]: borrow of moved value: `item.my_first_string` --> src/lib.rs:14:30 | 13 | my_second_string: item.my_first_string, | -------------------- value moved here 14 | string_is_empty: item.my_first_string.is_empty(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value borrowed here after move | = note: move occurs because `item.my_first_string` has type `String`, which does not implement the `Copy` trait
原始代码
struct Foo { my_first_string: String, } struct Bar { my_second_string: String, string_is_empty: bool, } impl From<Foo> for Bar { fn from(item: Foo) -> Self { Bar { my_second_string: item.my_first_string, string_is_empty: item.my_first_string.is_empty(), } } }
解决方案
不需要调用clone(),有几种符合Rust所有权规则的实现方式:
方式一:先计算状态再移动字段
先借用字段计算空值状态,再移动字段到新结构体,全程无额外开销:
impl From<Foo> for Bar { fn from(item: Foo) -> Self { let string_is_empty = item.my_first_string.is_empty(); Bar { my_second_string: item.my_first_string, string_is_empty, } } }
方式二:解构结构体提取字段
通过模式匹配直接解构Foo,把字符串绑定到临时变量,写法更简洁:
impl From<Foo> for Bar { fn from(Foo { my_first_string }: Foo) -> Self { let string_is_empty = my_first_string.is_empty(); Bar { my_second_string: my_first_string, string_is_empty, } } }
方式三:通过AsRef获取引用
利用AsRef<str>获取字符串的不可变引用,在移动前完成状态检查:
impl From<Foo> for Bar { fn from(item: Foo) -> Self { let string_ref = item.my_first_string.as_ref(); Bar { my_second_string: item.my_first_string, string_is_empty: string_ref.is_empty(), } } }
内容的提问来源于stack exchange,提问作者Uclydde
相关产品推荐
相关产品推荐

