公開技術情報

[English] [Japanese]

10.4. 可変長引数、戻り値 編

可変長引数、戻り値

引数、 戻り値に … を利用することで、 可変長引数、可変長戻り値の関数を定義できます。

… を利用したサンプルを次に示します。

// @lnsFront: ok
fn func( ... ) : int, ... {
   let argList = [ ... ];
   let mut total = 0;
   foreach arg in argList {
      when! arg {
         total = total + arg@@int;
      }
   }
   return total, ...;
}

print( func( 1, 2, 3, 4 ) ); // 10 1 2 3 4

上記の例では、与えられた可変長引数の値を合計し、 合計値と与えられた可変長引数を返す関数 func() を定義、実行しています。

関数本体で … を使用することで、可変長引数そのものを示します。 ここで … は、 0 個以上の stem! の値となります。 stem! については後述します。

可変長引数をもつ関数をコールする側は、 0 個以上のあらゆる型の引数を指定できます。

Generics

上記の通り … を利用することで、可変長引数、戻り値を宣言できます。

しかし、 … の値は全て stem! として扱うため型情報が失なわれてしまいます。

上のサンプルでも、 func() には int のデータを渡しているのに、 型情報が失なわれるため func() 内で値にアクセスするには unwrap やキャストが必要になっています。

型情報を保つには、次のように ...<type> を使用します。

// @lnsFront: ok
fn func( ...<int> ) : int, ...<int> {
   let argList = [ ... ];
   let mut total = 0;
   foreach arg in argList {
      total = total + arg;
   }
   return total, ...;
}
print( func( 1, 2, 3, 4 ) ); // 10 1 2 3 4

...<int> を使用することで、 int の型情報を保持したまま可変長引数、戻り値を扱うことが出来ます。

なお、次のサンプルの func1() と func2() は同義です。

// @lnsFront: ok
fn func1( ...<stem!> ) {
   print( ... );
}
fn func2( ... ) {
   print( ... );
}
func1( 1, "abc" );
func2( 1, "abc" );