Rust 元组参数的执行顺序是什么?

hzq*_*elf 12 rust

如下代码所示,我想封装一个定时函数,返回一个闭包的结果和执行时间。

use tap::prelude::Pipe;
use std::time::{Instant, Duration};

pub fn measure_time_with_value<T>(f: impl FnOnce() -> T) -> (T, Duration) {
    Instant::now().pipe(|s| (f(), s)).pipe(|(f, s)| (f, s.elapsed()))
}
Run Code Online (Sandbox Code Playgroud)

但是不知道tuple参数的执行顺序是不是从左到右,即是否可以简化为如下代码:

pub fn measure_time_with_value<T>(f: impl FnOnce() -> T) -> (T, Duration) {
    Instant::now().pipe(|s| (f(), s.elapsed()))
}
Run Code Online (Sandbox Code Playgroud)

sk_*_*ant 13

来自Rust 参考,“表达式”一章,“操作数的评估顺序”小节(由我突出显示):

操作数的评估顺序

下面的表达式列表都以相同的方式计算它们的操作数,如列表后面所述。其他表达式要么不接受操作数,要么按照各自页面中的描述有条件地评估它们。

  • 解引用表达式
  • 错误传播表达式
  • 否定表达式
  • 算术和逻辑二元运算符
  • 比较运算符
  • 类型转换表达式
  • 分组表达式
  • 数组表达式
  • 等待表达式
  • 索引表达式
  • 元组表达式
  • 元组索引表达式
  • 结构表达式
  • 调用表达式
  • 方法调用表达式
  • 字段表达式
  • 中断表达式
  • 范围表达式
  • 返回表达式

这些表达式的操作数在应用表达式的效果之前进行评估。使用多个操作数的表达式按照源代码中的描述从左到右求值。

[...]

例如,接下来的两个方法调用将始终以相同的顺序调用:

let mut one_two = vec![1, 2].into_iter();
assert_eq!(
    (1, 2),
    (one_two.next().unwrap(), one_two.next().unwrap())
);
Run Code Online (Sandbox Code Playgroud)

所以是的,因为保证元组表达式的评估是从左到右的,所以您的代码可以按照您描述的方式进行简化。