Rust中函数参数评估和结构初始化的顺序是什么?

Vic*_*voy 12 rust

是否在Rust中定义了函数参数评估的顺序?

fn f(a: u64, b: u64, c: u64) {}
fn g() -> u64 { 0 }
fn h() -> u64 { 1 }
fn i() -> u64 { 2 }

fn main() {
    f(g(), h(), i());
}
Run Code Online (Sandbox Code Playgroud)

另外,我担心结构的初始化顺序:

fn f() {}
fn g() {}

A {
    a: f(),
    b: g(),
}
Run Code Online (Sandbox Code Playgroud)

是保证顺序a,然后b

对于我的特定用例,我将diesel像这样在事务中初始化一个结构:

db_connection.transaction(||
    Ok(CompanyAndUser {
        company: companies::register_company(...)?, // performs diesel insert
        user: users::register_user(...)?, // performs diesel insert
    })
);
Run Code Online (Sandbox Code Playgroud)

显然,我希望对事务中的这两个柴油调用进行排序。不幸的是,我没有找到任何有关此的信息。另外,我发现了一些或多或少的相关信息,但是它已经很老了。

Fre*_*ios 6

正式

现在,参考中未指定评估顺序:

陈述和表达

评估表达式的规则包括指定由表达式产生的值和对其子表达式本身求值的顺序。

让我们看一下这些子表达式:

  • 有关调用表达式另一页中,未对函数调用中的优先级进行任何指定。

  • 但是,关于struct初始化,参考似乎说评估的顺序遵循声明的顺序:

    带有用大括号括起来的字段的struct表达式允许您以任何顺序(由我强调)为每个单独的字段指定值。

    如果参考文献指出它可以“以任何顺序”工作,那么我想那是因为顺序很重要。

非正式地


为了回答您的具体担忧,显而易见的解决方案是将您的操作转换为语句:

db_connection.transaction(|| {
    let company = companies::register_company(...)?; // performs diesel insert
    let user = users::register_user(...)?; // performs diesel insert

    Ok(CompanyAndUser { company, user })
});
Run Code Online (Sandbox Code Playgroud)

  • 这个答案已经过时了。该顺序已记录并保证现在是从左到右:https://doc.rust-lang.org/reference/expressions.html#evaluation-order-of-operands。_“采用多个操作数的表达式按照源代码中的方式从左到右求值。”_ (2认同)