If I want to unpack a tuple and pass it as arguments is there a way to do this:
//Does not compile fn main() { let tuple = (10, Vec::new()); foo(tuple); } fn foo(a: i32, b: Vec<i32>) { //Does stuff. }
Instead of having to do this:
fn main() { let tuple = (10, Vec::new()); foo(tuple.0, tuple.1); } fn foo(a: i32, b: Vec<i32>) { //Does stuff. }
A tuple can also be passed as a single argument to the function. Individual tuples as arguments are just individual variables. A function call is not an assignment statement; it's a reference mapping.
Unpacking tuples means assigning individual elements of a tuple to multiple variables. Use the * operator to assign remaining elements of an unpacking assignment into a list and assign it to a variable.
We can do the tuple unpacking right inside the for loop itself because anything you can put on the left-hand side of the equal sign, you can put in between the for and the in in a for loop.
Strictly speaking, a function can only return one value, but if the value is a tuple, the effect is the same as returning multiple values. For example, if you want to divide two integers and compute the quotient and remainder, it is inefficient to compute x//y and then x%y .
On a nightly compiler:
#![feature(fn_traits)] fn main() { let tuple = (10, Vec::new()); std::ops::Fn::call(&foo, tuple); } fn foo(a: i32, b: Vec<i32>) { }
There is AFAIK no stable way to do that.
There is a way, using the magic of pattern matching:
fn main() { let tuple = (10, Vec::new()); foo(tuple); } fn foo((a, b): (i32, Vec<i32>)) { // do stuff }
As per Rust reference:
As with let bindings, function arguments are irrefutable patterns, so any pattern that is valid in a let binding is also valid as an argument.
So you can specify an argument like:
(a, b): (i32, Vec<i32>)
just like you would in a let
statement.
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