web-dev-qa-db-ja.com

可変数の引数を持つ関数を作成するにはどうすればよいですか?

Rustで引数の数が可変の関数を作成するにはどうすればよいですか?

このようなJavaコード:

void foo(String... args) {
    for (String arg : args) {
        System.out.println(arg);
    }
}
33
Tiago

一般に、-Rustは可変引数をサポートしません。ただし、可変引数を使用するCコードと相互運用する場合を除きます。

thisの場合、引数はすべて同じ型であるため、スライスを受け入れることができます。

fn foo(args: &[&str]) {
    for arg in args {
        println!("{}", arg);
    }
}

fn main() {
    foo(&["hello", "world", "I", "am", "arguments"]);
}

プレイグラウンド

それを超えて、オプションの引数を明示的に受け入れることができます:

fn foo(name: &str, age: Option<u8>) {
    match age {
        Some(age) => println!("{} is {}.", name, age),
        None      => println!("Who knows how old {} is?", name),
    }
}

fn main() {
    foo("Sally", Some(27));
    foo("Bill", None);
}

プレイグラウンド

オプションであるかどうかにかかわらず、多くの引数を受け入れる必要がある場合は、ビルダーを実装できます。

struct Arguments<'a> {
    name: &'a str,
    age: Option<u8>,
}

impl<'a> Arguments<'a> {
    fn new(name: &'a str) -> Arguments<'a> {
        Arguments {
            name: name,
            age: None
        }
    }

    fn age(self, age: u8) -> Self {
        Arguments {
            age: Some(age),
            ..self
        }
    }
}

fn foo(arg: Arguments) {
    match arg.age {
        Some(age) => println!("{} is {}.", arg.name, age),
        None      => println!("Who knows how old {} is?", arg.name),
    }
}

fn main() {
    foo(Arguments::new("Sally").age(27));
    foo(Arguments::new("Bill"));
}

プレイグラウンド

37
Shepmaster
fn variable_func<T>(_vargs: &[T]) {}

fn main() {
    variable_func(&[1]);
    variable_func(&[1, 2]);
    variable_func(&["A", "B", "C"]);
}
3
creativcoder

タイプが異なる一般的なケースでは、マクロを使用できます。

macro_rules! print_all {
    ($($args:expr),*) => {{
        $(
            println!("{}", $args);
        )*
    }}
}

fn main() {
    print_all!(1, 2, "Hello");
}

プレイグラウンド

別の例として、引数を折りたたむ場合は、次のようなことができます。

macro_rules! sum {
    ($($args:expr),*) => {{
        let result = 0;
        $(
            let result = result + $args;
        )*
        result
    }}
}

fn main() {
    assert_eq!(sum!(1, 2, 3), 6);
}

プレイグラウンド

別の例については、 Rust bookのvec![...]の簡易実装 を参照してください。

0
Justin