Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如果尚未设置嵌套在多个选项中的值,如何设置这些值?_Rust_Config_Mutability - Fatal编程技术网

Rust 如果尚未设置嵌套在多个选项中的值,如何设置这些值?

Rust 如果尚未设置嵌套在多个选项中的值,如何设置这些值?,rust,config,mutability,Rust,Config,Mutability,我有如下配置设置: #[derive(Debug, Deserialize, Serialize)] struct Config { defaults: Option<Default>, } #[derive(Debug, Deserialize, Serialize)] struct Default { duration: Option<Millis>, } #[derive(Serialize, Deserialize, Debug)] struc

我有如下配置设置:

#[derive(Debug, Deserialize, Serialize)]
struct Config {
    defaults: Option<Default>,
}

#[derive(Debug, Deserialize, Serialize)]
struct Default {
    duration: Option<Millis>,
}

#[derive(Serialize, Deserialize, Debug)]
struct Millis(u64);
除此之外,我还没有找到一种方法来绕过那些
unwrap
s来按需创建值,这甚至更加冗长

if cfg.defaults.is_none() {
    cfg.defaults = Some(Default { duration: None });
}

if cfg.defaults.as_mut().unwrap().duration.is_none() {
    cfg.defaults.as_mut().unwrap().duration = Some(Millis(1234));
}

“方法”是什么?

我认为最好的方法是使用模式匹配:

if let Some(Config { defaults: Some(Default { duration: Some(ref mut millis) }) }) = cfg {
    *millis = 1234;
}
或者,如果让s:

if let Some(Config { ref mut defaults }) = cfg {
    if let Some(Default { ref mut duration }) = *defaults {
        *duration = Some(Millis(1234))
    }
}
然而,这不会根据需要创造价值。据我所知,没有简单的无样板的方法可以做到这一点。其中一种方法是定义自己的访问器方法,该方法将在访问时处理默认实例化:

impl Config {
    fn defaults(&mut self) -> &mut Default {
        if let Some(ref mut defaults) = *self.defaults {
            defaults
        } else {
            self.defaults = Some(Defaults::new());  // assuming that Defaults::new() exists
            self.defaults.as_mut().unwrap()
        }
    }
}
如果您对每个结构的每个字段都有这样的方法,您将能够做到:

*cfg.defaults().duration() = 1234;
这就是该方法的目的:

#[derive(Debug)]
struct Config {
    defaults: Option<Default>,
}

#[derive(Debug)]
struct Default {
    duration: Option<Millis>,
}

#[derive(Debug)]
struct Millis(u64);

fn main() {
    let mut config = Config { defaults: None };

    config
        .defaults
        .get_or_insert(Default { duration: None })
        .duration
        .get_or_insert(Millis(0))
        .0 = 42;

    // Config { defaults: Some(Default { duration: Some(Millis(42)) }) }
    println!("{:?}", config);
}
#[派生(调试)]
结构配置{
默认值:选项,
}
#[导出(调试)]
结构默认值{
持续时间:选择,
}
#[导出(调试)]
结构毫秒(u64);
fn main(){
让mut config=config{defaults:None};
配置
.违约
.get_或_insert(默认值{持续时间:无})
期间
.get_或_insert(毫秒(0))
.0 = 42;
//配置{默认值:一些(默认值{持续时间:一些(毫秒(42))})
println!(“{:?}”,配置);
}

不错!如果获得默认值的计算代价很高,那么还有一个
get\u或
。正是我想要的,谢谢!虽然最后一个get_或_insert可以插入实际数据,但我怀疑它是为了演示而这样写的
#[derive(Debug)]
struct Config {
    defaults: Option<Default>,
}

#[derive(Debug)]
struct Default {
    duration: Option<Millis>,
}

#[derive(Debug)]
struct Millis(u64);

fn main() {
    let mut config = Config { defaults: None };

    config
        .defaults
        .get_or_insert(Default { duration: None })
        .duration
        .get_or_insert(Millis(0))
        .0 = 42;

    // Config { defaults: Some(Default { duration: Some(Millis(42)) }) }
    println!("{:?}", config);
}