function

関数を定義します。


taiseiue | 2022-01-15

概要

関数(function) とは、特定の操作やタスクを実行するためにまとまった処理のかたまりのことです。 関数を使用すると、何度も同じ処理を行う部分を再利用することができるうえ、コードを構造化し、保守性を向上させるのに役立ちます。 AliceScriptの関数はデリゲート型を通して第一級関数としての性質を持ちます。

AliceScriptを用いたプログラミングでは、何度も使用する処理でなくても、特定の処理単位で関数にすることをオススメします。

この記事では、AliceScript 2.3以前を対象に説明しています。Alice3.0以降を使用している場合は、「関数」をご覧ください。

定義

名前空間: Alice
アセンブリ: Losetta.dll

AliceScript
namespace Alice;
public .command void function string funcName(params type args)
{
  //...
}
引数
funcName 定義する関数の識別子。
params type args 定義する関数に付与する引数と型(必要な場合)

対応
AliceScript RC1、RC2、GM、2.0、2.1、2.2、2.3
AliceSister GM、2.0、2.1、2.2、2.3
Losetta 0.8、0.9

Alice2.3以降ではfunctionはキーワードとして定義されます。

基本

関数は、クラスやスコープ内で修飾子(overrideやvirtualなど)とともに、関数の名前および引数を指定して宣言されます。

引数はかっこで囲み、各引数をコンマで区切ります。括弧内を空にすると、関数で引数が不要なことを意味します。

定義された関数は、関数の定義された後で使用できるようになります。

次の例にはSayHello関数が定義されています。これをユーザー定義関数といいます。SayHelloが呼び出されたとき、標準出力にHello,World!を書き込みます。

AliceScript
function SayHello(){
    print("Hello,World");
}
SayHello();//出力例:Hello,World

関数は、定義されるまで使用できません。次の例を参照してください。

```cs title="AliceScript" hl_line="1" SayHello();//例外発生:0x01 function SayHello(){ print("Hello,World"); }

AliceScriptでは関数の名前を、識別子と呼びます。識別子の名前付けルールなどについては、[識別子](./identifier.md)を参照してください。
### 戻り値
関数は、呼び出し元に[return](./return.md)キーワードを使用して値を返すことができます。関数の戻り値は呼び出し元でそのまま値として使用できます。次に例を示します。

```cs title="AliceScript"
function ReturnHello()
 {
   return "Hello,World!";
 }
print(ReturnHello());
//出力:Hello,World!

また、returnキーワードは、関数の実行をその時点で終了します。任意の場面で関数の実行を中止したい場合、 値を持たないreturnキーワードを使用できます。次に例を示します。

AliceScript
function ShowHello()
 {
   print("Hello");
   return;
   print("Hello,(again)");//この行は、returnキーワードよりも後にあるため実行されません
 }
//出力:Hello

引数

関数を定義する際には、必要な引数の名前を指定します。呼び出し元のコードから関数を呼び出すときに引数に具体的な値を指定します。次に例を示します。

AliceScript
function AddNumber(numA,numB)
 {
   return numA + numB;
 }
AddNumber(1,2);//戻り値:3

また、引数にnumberstringなどの型指定修飾子を使用すると、その型の値のみを引数として受け入れるようになり、予期しない型を使用した呼び出しを防ぐことができます。次に例を示します。

AliceScript
function Add(number a,number b)
{
   return a+b;
}
Add(1,2);//戻り値:3
Add("1","2");//例外発生

さらに、引数にparamsキーワードを使用すると、可変長個の引数を受け取る引数を指定できます。paramsの型は常にARRAYとなります。 ひとつの関数内では、paramsキーワードより後に引数を指定することができません。次に例を示します。

AliceScript
function PrintAllArgs(params args)
 {
   foreach(arg in args)
   {
     print(arg);
   }
 }
PrintAllArgs("Hello","World");
//出力:Hello
       World
PrintAllArgs();
//出力:(何も出力されません)

スコープ

関数は、変数と同じように、そのスコープ内で一意な名前である必要があります。スコープの範囲内では、基本的に同じ名前の関数を宣言することはできませんし、反対にスコープの外に出ると、その範囲内で定義した関数は使用できません。しかし、すでに定義された関数がオーバーライド可能属性を持っている場合は、override修飾子を使ってその関数を上書きできます。次に例を示します。

AliceScript
virtual function SayHello()
 {
    print("Hello,World");
 }
SayHello();//出力例:Hello,World
override function SayHello()
 {
    print("Hello,Bonjur");
 }
SayHello();//出力例:Hello,Bonjur

その関数を、現在のスコープの範囲外で使用できるようにするには、その関数にpublic修飾子を使用することそれをグローバル関数として宣言する必要があります。次に例を示します。

AliceScript
function RegisterGlobalFunction()
 {
     public function SayHello()
      {
          print("Hello,World");
      }
 }
RegisterGlobalFunction();
SayHello();//出力例:Hello,World

拡張メソッド

拡張メソッドを使用すると、新規に型を作成することなく既存の型にメソッドを追加できます。拡張メソッドに使用する関数はグローバル関数である必要があり、現在の型の変数が代入される引数にthisキーワードを使用します。

次の例は、現在の文字列の語数を数える(正確には、スペースで区切られた語の数を数える)WorldCountメソッドをstring型に登録します。

AliceScript
public function WordCount(this string str)
 {
    return str.Split(" ").Length;
 }
var text = "Hello Extension Methods";
print(text.WordCount());//出力例:3

登録したい引数の型指定修飾子をthisキーワードの後に記述します。これを省略すると、variable型に登録されます。複数のthisキーワードを使用することはできません。拡張メソッドにはvirtual属性およびoverride属性を付与することもできます。標準の型メソッドのオーバーライド可否については変数を参照してください。

デリゲートへの暗黙的な変換

ほとんどのネイティブ関数とユーザー定義関数は、デリゲート型の変数へと暗黙的に変換できます。ユーザー定義関数を丸括弧なしで呼び出すと、それはその関数をデリゲート型に変換されたオペランドと認識されます。次に例を示します。

AliceScript
function SayHello()
 {
    print("Hello,World");
 }
var hello=SayHello;//helloは、DELEGATE型を表します
hello();//出力:Hello,World
ただし、以下の属性を持っている関数を暗黙的に変換することはできません。

  • 言語構造
  • 関数の区切り文字の空白をサポート
  • 単一の引数のみ関数の区切り文字の空白をサポート

また、FunctionBase型を継承しない関数も、この機能をサポートしません。

属性

AliceScriptではさまざまな機能や構造が関数で設計されているため、必要に応じて関数に特別な機能を持たせることが可能です。属性の一覧を以下に示します。

属性の名前 修飾子 概要
一般 指定不要 通常の関数です。引数などは自動的にチェックされ実行されます。
関数の区切り文字の空白をサポート command 関数の呼び出し時に丸括弧の代わりに空白文字が使用できます。
単一の引数のみ関数の区切り文字の空白をサポート 指定不可 関数の引数がひとつのみの場合に関数の呼び出し時に丸括弧の代わりに空白文字が使用できます。
言語構造 指定不可 言語構造です。さまざまな形で使用できるため引数の自動チェックや最適化が実行されません。
オーバーライド可能 virtual オーバーライド可能な関数です。
オーバーライド override 既存の関数をオーバーライドします。この関数をオーバーライドすることもできます。
グローバル関数 public すべてのスコープで使用可能な関数です。