Rust中如何将Option<&str>转为Option<String>以简化结构体初始化
解决方案
要实现不用to_string()就能用字符串字面量初始化Foo结构体,同时保持字段为Option<String>的要求,有几种实用方法:
方法1:实现通用构造函数
给Foo添加一个支持自动转换的构造函数,利用Into trait兼容多种输入类型:
struct Foo { _a: Option<String>, } impl Foo { fn new(a: impl Into<Option<String>>) -> Self { Foo { _a: a.into() } } } fn main() { // 直接传入字符串字面量 let _unused1 = Foo::new("foobar"); // 也支持Option包裹的字面量 let _unused2 = Foo::new(Some("foobar")); // 支持None let _unused3 = Foo::new(None); }
这个构造函数会自动把&str或Option<&str>转换成Option<String>,完全符合需求。
方法2:实现From trait
如果只需要支持字符串字面量直接生成Foo,可以实现From<&str>:
struct Foo { _a: Option<String>, } impl From<&str> for Foo { fn from(s: &str) -> Self { Foo { _a: Some(s.to_string()) } } } fn main() { let _unused = Foo::from("foobar"); // 也可以用into()转换 let _unused2: Foo = "foobar".into(); }
方法3:用宏简化初始化
如果坚持想用结构体字面量的写法,可以写一个简单的宏来自动完成转换:
struct Foo { _a: Option<String>, } macro_rules! foo { ($a:expr) => { Foo { _a: Some($a.to_string()) } }; () => { Foo { _a: None } }; } fn main() { let _unused = foo!("foobar"); let _unused_none = foo!(); }
这些方法都能保证Foo内部持有String对象,完全兼容原有API,同时省去手动调用to_string()的麻烦。
内容的提问来源于stack exchange,提问作者Mihai Galos
相关产品推荐
相关产品推荐

