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


102

在以下示例中,我更希望在字段的声明中为结构中的每个字段分配一个值。另外,它实际上需要为每个字段添加一条附加语句以为这些字段分配一个值。我要做的就是在实例化该结构时分配默认值。

有更简洁的方法吗?

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,
        }
    }
}

Answers:


161

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

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

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

let p = cParams { iInsertMax: 10, ..Default::default() };

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

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

但是,建议您稍微更改一下数据结构,并使用Option<i64>而不是i64。我不知道您的代码的上下文,但是看起来您正在使用特殊值-1表示特殊含义“无限”或“没有最大值”。在Rust中,我们使用Option来表示可选的当前值。无需-1破解。一个选项可以是NoneSome(x)其中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() };

1
谢谢,我快速阅读了一下,但是我将重新阅读以更好地理解。我认为某些语言使用的“自然”默认值适合我,例如零,错误,“”等。我确实知道,要解决的问题比我的小“问题”要广泛。陈述能力 “ iVal:i64 = 0”将解决我的更多需求,但是我想那不会发生。“#[deriving(Default)]”应该可以解决我的大部分需求。我不确定为什么我在测试程序中使用-1,但是不需要(历史记录)。能够在定义字段的位置就地分配值将非常有用(IMHO)。
Brian Oh

9
@BrianOh,相切地,struct Foo { val: i64 = 0 }已经提出了“结构字段的默认值”(例如),因此可能会在以后的版本中出现。
休恩

如果将其实现为IMO,则更好-“ struct foo {....”。我按照您的建议进行了更改,使用问题中所写的结构和默认值。这当然更适合我,而且更加简洁。不熟悉语法,我遇到的一个小问题是不知道所有默认值的语法。IE:我使用了“ = cParams {iInsertMax:10,..Default :: default()};”,但实际上我希望“ iInstanceMax”也成为默认值。IMO最好将“#[deriving(Default)]”作为该结构的一部分,但我想替代方法更适合编译器。
Brian Oh

2
非常感谢。恕我直言,默认值应该是默认值。IE浏览器 我认为没有必要指定Default:default等。我也认为应该为字段定义一个值。那只是从我简单的角度来看,我意识到Rust的设计是安全的,并且存在比我更广阔的视野。当一个人学习语言(或至少是我)时,当前的实现似乎有点麻烦。Rust不是一种简单的语言恕我直言,并且可以做得更多来简化它,至少对我来说更好。
Brian Oh

2
实现Default结构时是否需要为所有字段定义默认值?
马修·史蒂文森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.