Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to unpack a tuple into function arguments?

Tags:

tuples

rust

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. } 
like image 707
HiDefender Avatar asked Oct 05 '16 15:10

HiDefender


People also ask

Can you pass tuples as arguments for a function?

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.

Can you unpack a tuple?

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.

Is it possible to unpack tuple items using for loop?

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.

Is it possible to return tuple as values?

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 .


2 Answers

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.

like image 80
mcarton Avatar answered Sep 23 '22 04:09

mcarton


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.

like image 34
ljedrz Avatar answered Sep 21 '22 04:09

ljedrz