関数
LuneScript の関数定義、呼び出し、および高度な機能について説明します。
定義
関数は fn キーワードを使って定義します。
// 引数なし、戻り値なし
fn hello() {
print( "Hello" );
}
// 引数あり、戻り値あり
fn add( val1: int, val2: int ): int {
return val1 + val2;
}
公開関数
モジュール外に公開するには pub を付けます。公開関数はトップレベル(最上位スコープ)でのみ定義可能です。
pub fn globalFunc() { print("global"); }
多値返却
LuneScript は複数の値を一度に返すことができます。
fn div_mod( a: int, b: int ): int, int {
return a / b, a % b;
}
let d, m = div_mod( 10, 3 );
print( d, m ); // 3, 1
多値返却の注意点 (Lua/LuneScript の仕様)
関数呼び出しを引数として渡す場合、最後の引数として渡された場合のみ、全ての戻り値が展開されます。
fn func(): int, int { return 1, 2; }
print( func() ); // 1, 2 (すべて展開)
print( func(), 10 ); // 1, 10 (2つ目の戻り値は捨てられる!)
print( 0, func() ); // 0, 1, 2 (すべて展開)
意図せず戻り値が捨てられる事故を防ぐため、LuneScript では多値を引数として渡す際、明示的に ** を付けることを推奨しています(将来的に必須になる可能性があります)。
fn func(): int, int { return 1, 2; }
fn func2( ... ) {}
func2( func()** ); // 多値をすべて渡すことを明示
クロージャと匿名関数
名前のない関数(匿名関数)を作成し、変数に代入したり関数の引数として渡すことができます。
fn run( cb: form ) {
cb();
}
let val = 10;
run( fn() {
print( val ); // 外部変数をキャプチャ (クロージャ)
} );
Form (関数型)
関数の型を表すには form キーワードを使用します。ただし、単なる form 型は「任意の引数、任意の戻り値を持つ関数」という広すぎる型(実質
stem! のようなもの)です。
特定の厳密なシグネチャを持つ関数型を定義するには、form 宣言を使用します。
// int を受け取り int を返す関数型 'IntFunc' を定義
form IntFunc( val: int ): int;
fn exec( f: IntFunc, v: int ) {
print( f( v ) );
}
exec( fn( v: int ): int { return v * 2; }, 10 ); // 20
可変長引数
... を使用して可変長引数を定義できます。
fn dumps( ... ) {
let list = [ ... ]; // リストに変換
foreach val in list {
print( val );
}
}
dumps( 1, "test", true );
型を指定したい場合は、Generics を使用するか、リストで受け取る設計を検討してください。
引数の省略
Nilable 型の引数は、呼び出し時に省略可能です。省略された場合 nil が渡されます。
fn opt( val: int! ): int {
return unwrap val default 0;
}
print( opt( 10 ) ); // 10
print( opt() ); // 0 (val is nil)
省略を明示するために ## を使うことができます(opt( ## ))。これは「意図して省略した」ことをコード上で明確にするためです。