【发布时间】:2021-01-16 16:27:29
【问题描述】:
假设我有一个包含Option<Resource> 的结构,其中Resource 是我需要使用的某种类型,需要分配外部资源(在实际情况下是GPU 内存),因此可能会失败。在一个方法中,如果尚未完成分配,我想尝试分配,但如果失败则传播或处理错误。
如果不是失败案例,Option::get_or_insert_with 将是完美的。事实上,我想到的最整洁的解决方案涉及一个 unwrap(),这是不优雅的,因为它看起来像一个潜在的恐慌:
struct Container {
resource: Option<Resource>,
...
}
impl Container {
...
fn activate(&mut self) -> Result<(), Error> {
if self.resource.is_none() {
self.resource = Some(Resource::new()?);
}
let resource: &mut Resource = self.resource.as_mut().unwrap();
// ... now do things with `resource` ...
Ok(())
}
...
}
有没有比这更轻松地初始化Option 的方法?需要明确的是,我并不是单独寻求避免unwrap(),而是整体可读性。如果替代方案更加复杂和间接,我宁愿坚持下去。
完整的示例代码(on Rust Playground):
#[derive(Debug)]
struct Resource {}
#[derive(Debug)]
struct Error;
impl Resource {
fn new() -> Result<Self, Error> {
Ok(Resource {})
}
fn write(&mut self) {}
}
#[derive(Debug)]
struct Container {
resource: Option<Resource>,
}
impl Container {
fn new() -> Self {
Self { resource: None }
}
fn activate(&mut self) -> Result<(), Error> {
if self.resource.is_none() {
self.resource = Some(Resource::new()?);
}
self.resource.as_mut().unwrap().write();
Ok(())
}
}
fn main() {
Container::new().activate();
}
【问题讨论】:
标签: rust optional lazy-initialization