是否有更快/更短的方法来初始化Rust结构中的变量?

Bri*_* Oh 81 rust

在下面的示例中,我更倾向于在字段声明中为结构中的每个字段分配一个值.或者,它有效地为每个字段添加一个附加语句,以便为字段分配值.我想要做的就是在实例化结构时指定默认值.

有更简洁的方法吗?

struct cParams {
    iInsertMax: i64,
    iUpdateMax: i64,
    iDeleteMax: i64,
    iInstanceMax: i64,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

impl cParams {
    fn new() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Zar*_*ony 130

您可以通过实现Default特征为结构提供默认值.该default函数看起来像您当前的new函数:

impl Default for cParams {
    fn default() -> cParams {
        cParams {
            iInsertMax: -1,
            iUpdateMax: -1,
            iDeleteMax: -1,
            iInstanceMax: -1,
            tFirstInstance: false,
            tCreateTables: false,
            tContinue: false,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过仅提供非默认值来实例化结构:

let p = cParams { iInsertMax: 10, ..Default::default() };
Run Code Online (Sandbox Code Playgroud)

通过对数据结构进行一些小的更改,您可以利用自动派生的默认实现.如果您#[derive(Default)]在数据结构上使用,编译器将自动为您创建一个默认函数,使用其默认值填充每个字段.默认布尔值为false,默认积分值为0.

整数的默认值为0是一个问题,因为您希望整数字段默认为-1.您可以定义一个实现默认值-1的新类型,并使用它而不是i64在结构中.(我没有测试过,但它应该工作).

但是,我建议稍微更改您的数据结构并使用Option<i64>而不是i64.我不知道你的代码的上下文,但看起来你使用特殊值-1来表示特殊含义"无限",或"没有最大值".在Rust中,我们使用an Option来表示可选的现值.不需要-1 hack.一个选项可以是x None或者Some(x)你的位置i64.如果-1是唯一的负值,它甚至可能是无符号整数.默认Option值是None,因此对于建议的更改,您的代码可能如下所示:

#[derive(Default)]
struct cParams {
    iInsertMax: Option<u64>,
    iUpdateMax: Option<u64>,
    iDeleteMax: Option<u64>,
    iInstanceMax: Option<u64>,
    tFirstInstance: bool,
    tCreateTables: bool,
    tContinue: bool,
}

let p = cParams { iInsertMax: Some(10), ..Default::default() };
Run Code Online (Sandbox Code Playgroud)

  • @BrianOh,切向地,"结构字段的默认值"(即类似`struct Foo {val:i64 = 0}`)已被提出,因此可能出现在更高版本中. (6认同)
  • 为结构实现“默认”时是否需要为所有字段定义默认值? (5认同)
  • 谢谢,我快速阅读了,但我会重新阅读以更好地理解。某些语言使用的“自然”默认值,例如我相信零、假、“”等,适合我。我确实明白,比我要解决的小“问题”有更广泛的影响。陈述能力,例如。“iVal : i64 = 0”,将解决我更广泛的需求,但我想这不会发生。“#[deriving(Default)]”应该可以解决我的大部分需求。我不确定为什么在我的测试程序中使用 -1,但它不是必需的(历史性的)。能够在定义字段的原位分配值将非常有用(恕我直言)。 (2认同)
  • 非常感谢.恕我直言默认值应该是默认值.IE浏览器.我认为没有必要指定Default:default等等.我还认为应该能够为这些字段分配一个定义它们的值.这只是从我简单的角度来看,我意识到Rust的设计是安全的,并且有一个比我更广泛的视角.当一个人学习语言(或至少是我)时,当前的实现似乎有点麻烦.Rust不是一种简单的语言恕我直言,并且为了简化它可以做得越多,至少对我来说更好. (2认同)

SET*_*SET 42

如今,完全可以按照OP 8年前的要求去做

在字段声明中为结构中的每个字段分配一个值。

使用衍生箱:

#![allow(non_snake_case)]
#![allow(non_camel_case_types)]

use derivative::Derivative;

#[derive(Derivative)]
#[derivative(Debug, Default)]
struct cParams {
    #[derivative(Default(value = "-1"))]
    iInsertMax: i64,
    #[derivative(Default(value = "-1"))]
    iUpdateMax: i64,
    #[derivative(Default(value = "-1"))]
    iDeleteMax: i64,
    #[derivative(Default(value = "-1"))]
    iInstanceMax: i64,
    #[derivative(Default(value = "false"))]
    tFirstInstance: bool,
    #[derivative(Default(value = "false"))]
    tCreateTables: bool,
    #[derivative(Default(value = "false"))]
    tContinue: bool,
}

fn main() {
    println!("cParams: {:?}", cParams::default());
}
Run Code Online (Sandbox Code Playgroud)

另外,没有必要以这种方式定义布尔值的默认假值,因为Default无论如何都会将它们设置为该值

  • @at54321 希望不会,至少不会使用这种语法。这段代码看起来非常丑陋和冗长(在我看来)。如果必须这样做,那么最好只实现“默认”。不需要用这些东西让语言变得混乱,否则很快 Rust 就会看起来像 C++,这将是一个糟糕的主意。最好将其保留为板条箱,以便人们在需要时使用它。 (30认同)
  • 如果有一天能在标准库中看到类似的东西,那就太好了。 (19认同)