D-programming-functions
Dプログラミング-関数
この章では、Dプログラミングで使用される関数について説明します。
Dの関数定義
基本的な関数定義は、関数ヘッダーと関数本体で構成されます。
構文
return_type function_name( parameter list ) {
body of the function
}
ここに関数のすべての部分があります-
- 戻り値の型-関数は値を返す場合があります。 return_type は、関数が返す値のデータ型です。 一部の関数は、値を返さずに目的の操作を実行します。 この場合、return_typeはキーワード void です。
- 関数名-これは関数の実際の名前です。 関数名とパラメーターリストは一緒に関数シグネチャを構成します。
- パラメータ-パラメータはプレースホルダのようなものです。 関数が呼び出されると、パラメーターに値を渡します。 この値は、実パラメーターまたは引数と呼ばれます。 パラメーターリストは、関数のパラメーターのタイプ、順序、および数を参照します。 パラメーターはオプションです。つまり、関数にパラメーターを含めることはできません。
- 関数本体-関数本体には、関数の動作を定義するステートメントのコレクションが含まれています。
関数を呼び出す
次のように関数を呼び出すことができます-
function_name(parameter_values)
Dの関数タイプ
Dプログラミングは幅広い機能をサポートしており、以下にリストされています。
- 純粋な機能
- スロー機能
- 参照関数
- 自動機能
- 可変長関数
- 入出力関数
- プロパティ関数
以下に、さまざまな機能について説明します。
純粋な機能
純粋な関数とは、引数を通じてグローバルまたは静的な可変状態保存にアクセスできない関数です。 これにより、純粋な関数は渡されないものを何も変更しないことが保証されているという事実に基づいて最適化を有効にできます。つまり、関数が同じ引数に対して常に同じ結果を返すという保証です)。
import std.stdio;
int x = 10;
immutable int y = 30;
const int* p;
pure int purefunc(int i,const char* q,immutable int *s) {
//writeln("Simple print");//cannot call impure function 'writeln'
debug writeln("in foo()");//ok, impure code allowed in debug statement
//x = i; //error, modifying global state
//i = x; //error, reading mutable global state
//i =* p;//error, reading const global state
i = y; //ok, reading immutable global state
auto myvar = new int; //Can use the new expression:
return i;
}
void main() {
writeln("Value returned from pure function : ",purefunc(x,null,null));
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
Value returned from pure function : 30
スロー機能
nothrow関数は、クラスExceptionから派生した例外をスローしません。 スロー機能はスロー機能と共変です。
Nothrowは、関数が例外を発行しないことを保証します。
import std.stdio;
int add(int a, int b) nothrow {
//writeln("adding"); This will fail because writeln may throw
int result;
try {
writeln("adding");//compiles
result = a + b;
} catch (Exception error) {//catches all exceptions
}
return result;
}
void main() {
writeln("Added value is ", add(10,20));
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
adding
Added value is 30
参照関数
Ref関数を使用すると、関数を参照によって返すことができます。 これはref関数のパラメーターに似ています。
import std.stdio;
ref int greater(ref int first, ref int second) {
return (first > second) ? first : second;
}
void main() {
int a = 1;
int b = 2;
greater(a, b) += 10;
writefln("a: %s, b: %s", a, b);
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
a: 1, b: 12
自動機能
自動関数は、任意のタイプの値を返すことができます。 返される型に制限はありません。 自動タイプ関数の簡単な例を以下に示します。
import std.stdio;
auto add(int first, double second) {
double result = first + second;
return result;
}
void main() {
int a = 1;
double b = 2.5;
writeln("add(a,b) = ", add(a, b));
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
add(a,b) = 3.5
可変長関数
Variadiac関数は、関数のパラメーターの数が実行時に決定される関数です。 Cには、少なくとも1つのパラメーターを持つという制限があります。 しかし、Dプログラミングでは、そのような制限はありません。 以下に簡単な例を示します。
import std.stdio;
import core.vararg;
void printargs(int x, ...) {
for (int i = 0; i < _arguments.length; i++) {
write(_arguments[i]);
if (_arguments[i] == typeid(int)) {
int j = va_arg!(int)(_argptr);
writefln("\t%d", j);
} else if (_arguments[i] == typeid(long)) {
long j = va_arg!(long)(_argptr);
writefln("\t%d", j);
} else if (_arguments[i] == typeid(double)) {
double d = va_arg!(double)(_argptr);
writefln("\t%g", d);
}
}
}
void main() {
printargs(1, 2, 3L, 4.5);
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
int 2
long 3
double 4.5
入出力関数
inoutは、パラメーターのタイプと関数の戻りタイプの両方に使用できます。 これは、可変、const、および不変のテンプレートのようなものです。 可変性属性は、パラメーターから推定されます。 つまり、inoutは、推定された可変性属性を戻り値の型に転送します。 可変性がどのように変化するかを示す簡単な例を以下に示します。
import std.stdio;
inout(char)[] qoutedWord(inout(char)[] phrase) {
return '"' ~ phrase ~ '"';
}
void main() {
char[] a = "test a".dup;
a = qoutedWord(a);
writeln(typeof(qoutedWord(a)).stringof," ", a);
const(char)[] b = "test b";
b = qoutedWord(b);
writeln(typeof(qoutedWord(b)).stringof," ", b);
immutable(char)[] c = "test c";
c = qoutedWord(c);
writeln(typeof(qoutedWord(c)).stringof," ", c);
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
char[] "test a"
const(char)[] "test b"
string "test c"
プロパティ関数
プロパティにより、メンバー変数などのメンバー関数を使用できます。 @propertyキーワードを使用します。 プロパティは、要件に基づいて値を返す関連機能にリンクされています。 プロパティの簡単な例を以下に示します。
import std.stdio;
struct Rectangle {
double width;
double height;
double area() const @property {
return width*height;
}
void area(double newArea) @property {
auto multiplier = newArea/area;
width *= multiplier;
writeln("Value set!");
}
}
void main() {
auto rectangle = Rectangle(20,10);
writeln("The area is ", rectangle.area);
rectangle.area(300);
writeln("Modified width is ", rectangle.width);
}
上記のコードをコンパイルして実行すると、次の結果が生成されます-
The area is 200
Value set!
Modified width is 30