Rust中Option map()返回当前函数持有数据引用报错如何优雅解决
报错根因
直接对持有所有权的Option<Foo>调用map时,map会按值获取self的所有权,将内部的Foo实例移动到闭包作用域内。闭包返回的&str是指向这个临时Foo实例name字段的引用,闭包执行结束后临时Foo会被自动释放,该引用会成为悬垂引用,编译器直接拦截这类不安全代码。
零开销修复方案(无字符串复制、无需使用String类型)
只需要在调用map前,先对Option调用as_ref()方法,将Option<Foo>转换为Option<&Foo>,后续map闭包拿到的就是Foo的引用,不会触发所有权转移,返回的&str生命周期和外层的entity变量绑定,完全合法:
struct Foo { pub name: String, } fn is_empty(s: &str) -> bool { s.len() == 0 } fn main() { let entity = Some(Foo { name: "some-name".to_string() }); let name: &str = entity .as_ref() // 生成Option<&Foo>,不移动内部Foo的所有权 .map(|it| it.name.as_ref()) .unwrap_or("another-name"); println!("is it empty: {}", is_empty(name)); }
等价显式写法
如果偏好更直白的控制流,直接用match匹配引用也能达到完全相同的效果,运行时性能和上面的写法完全一致,同样没有任何额外开销:
let name: &str = match &entity { Some(foo) => foo.name.as_ref(), None => "another-name" };
说明:以上两种写法全程没有发生字符串堆复制,所有引用的生命周期都合法,没有额外的性能损耗,是这类场景下的最优实现。
内容的提问来源于stack exchange,提问作者billy voiderer
相关产品推荐
相关产品推荐

