Passing a tuple with an unknown number of arguments

Hi
Iis is possible to pass a tuple to a function and not know the number of arguments the tuple has, for example:


fn test (x: ()) {
   match x {
    (_) => println!("one arg"),
    (_,_) => println!("two arg"),
    (_,_,_) => println!("three arg"),
     _ => println!("way too many arg")
   }
}

I assume not, but I am not sure ...

thnx

You can use a slice:

fn test(x: &[i32]) {
    match x.len() {
        1 => println!("one arg"),
        2 => println!("two arg"),
        3 => println!("three arg"),
        _ => println!("way too many arg"),
    }
}
1 Like

Tuples are not variable-length containers. They're all independent types, each a kind of struct, just without names.

If length as concept exists in your problem, then tuples are not the solution.

5 Likes

Variadic tuples would be a start:

But even then, AIUI this would resolve at compile time, not a dynamic match like you suggest.

1 Like

Using a dyn Any approach might work, but it'd be messy and expensive to use:

fn foo(tuple: Vec<Box<dyn Any>>) { /**/ }

I'd recommend against using it, and instead using a trait should you really really need to use variable type tuples:

trait Bar<T> {
    type Output;
    fn call_me_with(value: T) -> Self::Output;
}

But this look suspiciously like an Fn* trait, in that case, using nightly you could use overloadable as follows:

#![feature(unboxed_closures, fn_traits)]
use overloadable::overloadable;

overloadable! {
    pub test as
    fn(x: ()) {
        
    },
    // Note that `(T,)` is a one-tuple because of the leading comma
    fn<T>(x: (T,)) {
        println!("one arg");
    },
    fn<T, U>(x: (T, U)) {
        println!("two arg");
    },
    fn<T, U, W>(x: (T, U, W)) {
        println!("three arg");
    },
    fn<T, U, W, Q>(x: (T, U, W, Q)) {
        println!("way too many arg");
    }
}
1 Like

frunk, but be warned, it isn't that easy to use. Lots of type-level machinery, and it increases compile times quite a lot when used in more than a few places.

3 Likes

What’s your use case? Do you expect all values to be of the same type? If so, could a Vec work for you? If not, you’re entering curious realms where the kinds of things you can do with arbitrary collections of values of arbitrary types are limited.

2 Likes