As shown in the following code, I want to encapsulate a timing function that returns the result and the execution time of a closure.
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()))
}
But I don’t know whether the execution order of the tuple parameters is from left to right, that is, whether it can be simplified to the following code:
pub fn measure_time_with_value<T>(f: impl FnOnce() -> T) -> (T, Duration) {
Instant::now().pipe(|s| (f(), s.elapsed()))
}
A tuple in rust is a finite heterogeneous compound data type, meaning it can store more than one value at once. In tuples there is no inbuilt method to add elements into a tuple. We can use the index to get the value of a tuple, and we also can not iterate over a tuple using for loop.
Conclusion. Above is how tuple is saved in Python and Rust. tuple in Python is immutable and the data struct is simpler than list . Rust optimizes the memory layout when using tuple .
Rust - Tuple. Tuple is a compound data type. A scalar type can store only one type of data. For example, an i32 variable can store only a single integer value. In compound types, we can store more than one value at a time and it can be of different types.
The most trivial data-structure, after a singular value, is the tuple. (A, B, C) // a three-tuple (a tuple with three elements), whose first element has type A, second type B, and third type C Rust tuples, as in most other languages, are fixed-size lists whose elements can all be of different types.
(A, B, C) // a three-tuple (a tuple with three elements), whose first element has type A, second type B, and third type C Rust tuples, as in most other languages, are fixed-size lists whose elements can all be of different types.
In this documentation the shorthand (T₁, T₂, …, Tₙ) is used to represent tuples of varying length. When that is used, any trait bound expressed on T applies to each element of the tuple independently. Note that this is a convenience notation to avoid repetitive documentation, not valid Rust syntax.
From the Rust reference, chapter "Expressions", subsection "Evaluation order of operands" (highlighting by me):
Evaluation order of operands
The following list of expressions all evaluate their operands the same way, as described after the list. Other expressions either don't take operands or evaluate them conditionally as described on their respective pages.
- Dereference expression
- Error propagation expression
- Negation expression
- Arithmetic and logical binary operators
- Comparison operators
- Type cast expression
- Grouped expression
- Array expression
- Await expression
- Index expression
- Tuple expression
- Tuple index expression
- Struct expression
- Call expression
- Method call expression
- Field expression
- Break expression
- Range expression
- Return expression
The operands of these expressions are evaluated prior to applying the effects of the expression. Expressions taking multiple operands are evaluated left to right as written in the source code.
[...]
For example, the two next method calls will always be called in the same order:
let mut one_two = vec![1, 2].into_iter(); assert_eq!( (1, 2), (one_two.next().unwrap(), one_two.next().unwrap()) );
So yes, as evaluation of tuple expressions is guaranteed to be from left to right, your code can be simplified in the way you described.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With