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()))
}

但是我不知道元组参数的执行顺序是否从左到右,也就是是否可以简化为下面的代码:

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

来自Rust参考,章节"表达式",小节"操作数的求值顺序";(我加亮):

操作数求值顺序

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

<
  • 废弃表达式/gh>错误传播表达式
  • <
  • 否定表达/gh>
  • 算术和逻辑二进制运算符
  • 比较运算符
  • 类型转换表达式
  • <
  • 分组表达式/gh><
  • 数组表达/gh><
  • 等待表达式/gh><
  • 索引表达式/gh><
  • 元组表达/strong>
  • 元组索引表达式<
  • 结构表达式/gh><
  • 调用表达式/gh>方法调用表达式
  • <
  • 字段表达式/gh><
  • 打破表达式/gh><
  • 范围表达式/gh><
  • 返回表达式/gh>

这些表达式的操作数在应用表达式的效果之前求值。包含多个操作数的表达式从左到右求值如源代码所示。

[…]

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

let mut one_two = vec![1, 2].into_iter();
assert_eq!(
(1, 2),
(one_two.next().unwrap(), one_two.next().unwrap())
);

所以,是的,由于元组表达式的求值保证从左到右,您的代码可以按照您描述的方式简化。

最新更新