return_type function_name( parameter list ) { body of the function }
一個基本的函式定義由函式頭和函式體。這裡是一個函式的所有部分:
Return Type: 函式可以返回一個值。該return_type是函式返回值的資料型別。有些函式沒有返回值執行所需的操作。在這種情況下,return_type是關鍵字void.
Function Name: 這是函式的實際名稱。函式名和引數列表一起構成了函式簽名。
Parameters: 引數是像一個預留位置。當呼叫一個函式,傳遞一個值給該引數。這個值被稱為實際引數或引數。引數列表是指型別,順序和一個函式的引數的數目。引數是可選的;也就是說,一個功能可以包含任何引數。
Function Body: 函式體包含了定義函式語句的集合。
我們可以呼叫函式使用下面的語法
function_name(parameter_values)
D程式設計支援廣泛的函式,它們如下面列出。
純函式
丟擲異常函式
參考函式
自動函式
可變引數函式
inout函式
屬性函式
各種函式功能說明。
純函式是無法通過他們的論據存取全域性或靜態的,可變的狀態儲存函式。這可以基於一個事實,即一個純函式是保證變異不被傳遞給它什麼,並在情況下,編譯器可以保證純函式不能改變它的引數,它可以啟用完整,功能純度(啟用優化即保證該函式總是返回相同的結果為相同的引數)。
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
丟擲異常函式不會丟擲從類Exception派生的任何異常。丟擲異常函式是協變與丟擲。
丟擲異常保證函式不發出任何異常。
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)); }
When we run the above program, we will get the following output.
adding Added value is 30
參考函式允許函式按參照返回。這類似於文獻的功能引數。
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
可變引數函式是其中一個函式引數的數量,在執行時確定的函式。在C中,存在具有ATLEAST一個引數的限制。但在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(" %d", j); } else if (_arguments[i] == typeid(long)) { long j = va_arg!(long)(_argptr); writefln(" %d", j); } else if (_arguments[i] == typeid(double)) { double d = va_arg!(double)(_argptr); writefln(" %g", d); } } } void main() { printargs(1, 2, 3L, 4.5); }
當我們執行上面的程式,我們會得到下面的輸出。
int 2 long 3 double 4.5
INOUT既可以用於函式的引數和返回型別中使用。這就像為可變的,常數,和不變的模板。可變性屬性從引數即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