Rust按需创建自有值:条件获取引用的惯用实现方法
按需创建自有值的Rust实现方式
这段代码编译失败的核心是生命周期不匹配——else分支里的b是块内局部变量,它的生命周期仅限于else代码块,而r的生命周期要覆盖整个main函数,无法引用一个已经被销毁的变量。下面是几种Rust里的惯用解决方式:
方式一:提前声明变量,扩大生命周期
把需要按需创建的变量b提前声明在外部作用域,让它的生命周期和现有值a、最终引用r保持一致:
String示例
fn main() { let condition = false; let a: String = "a".to_string(); let b; // 提前声明变量,预留生命周期 let r: &String = if condition { &a } else { b = "b".to_string(); &b }; println!("{}", r); }
自定义结构体S示例
struct S(i32); fn main() { let condition = false; let a: S = S(0); let b; let r: &S = if condition { &a } else { b = S(1); &b }; println!("{}", r.0); }
方式二:用Box<T>将值分配到堆上
通过Box把值放到堆内存中,两个分支的引用都指向堆上的数据,生命周期统一由Box实例管理:
String示例
fn main() { let condition = false; let a: String = "a".to_string(); let boxed_val = if condition { Box::new(a) // 将a转移到堆上 } else { Box::new("b".to_string()) }; let r: &String = &boxed_val; println!("{}", r); }
自定义结构体S示例
struct S(i32); fn main() { let condition = false; let a: S = S(0); let boxed_val = if condition { Box::new(a) } else { Box::new(S(1)) }; let r: &S = &boxed_val; println!("{}", r.0); }
方式三:使用Cow<T>实现克隆-on-write
如果类型实现了Clone trait,Cow可以灵活切换“引用现有值”和“持有自有值”的状态,避免不必要的克隆:
use std::borrow::Cow; fn main() { let condition = false; let a: String = "a".to_string(); let cow_val: Cow<String> = if condition { Cow::Borrowed(&a) // 引用已有值 } else { Cow::Owned("b".to_string()) // 创建并持有新值 }; let r: &String = cow_val.as_ref(); println!("{}", r); }
内容的提问来源于stack exchange,提问作者TSK
相关产品推荐
相关产品推荐

