參考自d程序設計語言---個人博客http://my.oschina.net/u/218155/blog?fromerr=SwOkb7Sw fllow mejava
d語言的函數很是豐富。我也只學了一點皮毛,但願能和你們共同探討。c++
最基本的函數和java,c,c++相似哦,是否是。數組
bool greater(int a, int b) { return a < b; }
對可變數組的單個值操做會改變可變數組的值閉包
對整個可變數組賦值不會改變值函數
//change data void func(int x){ x++;} void gunc(int[] x) {x=[1,2,3];} void sunc(int[] x){x[0] = x[1];} auto x = [1,2]; assert(gunc(x) == [1,2]); assert(sunc(x) == [2,2]);
d語言的查找的基本方法
.net
//find data like list bool findData(int[] need,int val){ foreach(v;need){ if(v == val) return true; } return false; } //find data in array int[] findList(int[] need, int val){ while(need.length > 0 && need[0] != val){ need = need[1..$]; } return need; } auto mylist = [1,2,3,4,5]; assert(findData(mylist,2) == true); assert(findList(mylist,2).length == 4); mylist = []; assert(findList(mylist,2) == []);
dlang支持經過在參數前增長ref改變參數的值,這個是後傳遞的是參數的地址哦。設計
void func_ref(ref int x){x++;} ref int func_ref_ref(ref int x){x++; return x;} int x = 0; func_ref(x); assert(x == 2); assert(func_ref_ref(func_ref_ref(x)) == 4);
dlang能夠在參數前加in讓參數只可讀,加out能夠將外部變量傳入函數裏面。相似引用code
int func_in(in int x,out int y){ y = x+1; return x; }
dlang中也支持靜態值blog
static int func_count = 0; void func_call(int x){ ++func_count; //writeln(func_count); }
dlang函數中的泛型,讓函數更加通用get
//the generic T[] findListG(T)(T[] list,T search){ while(list.length > 0 && list[0] != search){ list = list[1..$]; } return list; } int[] mylist = [1,2,3,4,5]; assert(findListG!(int)(mylist,3) == [3,4,5]); //int to double double[] mylist2 = [1,1.1,2.1,3.1,4.1,5.1,3]; assert(findListG(mylist2,3) == [3]); //assert(findListG(mylist2,"hi") == []);//error
dlang函數前能夠加上參數約束。typeof判斷類型,is判斷二者比較的結果是否是bool
T[] findListG2(T,E)(T[] list,E search) if(is(typeof(T[0] != search) == bool)) { while(list.length > 0 && list[0] != search){ list = list[1..$]; } return list; } assert(findListG2(mylist2,3) == [3]);//error
讓上面的find函數更加通用
T1[] findListG3(T1,T2)(T1[] longer, T2[] shorter) if(is(typeof(longer[0..1] == shorter) :bool)) { while(longer.length > shorter.length){ if(longer[0..shorter.length] == shorter) break; longer = longer[1..$]; } return longer; }
dlang中函數重載會根據參數的範圍調用函數,優先調用小範圍的。
bool myprint(int x){ return is(typeof(x) == int); } bool myprint(double x){ return is(typeof(x) == double); } myprint(1);//優先調用myprint(int x)
dlang的高階函數.容許使用函數別名
//senior function T[] findSenior(alias pred,T)(T[] input) if(is(typeof(pred(input[0])) == bool)) { for(;input.length >0;input = input[1..$]){ if(pred(input[0])) break; } return input; } auto senior_list = [22,3,12,-7,-9,32]; //調用函數 assert(findSenior!(function bool(int x){return x > 30;})(senior_list) == [32]); int z = 30; //senior function delegate調用委託函數。委託函數能夠訪問外部變量 assert(findSenior!(delegate bool(int x){return x > z;})(senior_list) == [32]); auto myfunc = function bool(int x){ return x < 0;}; auto senior_list2 = findSenior!(myfunc)(senior_list); //auto list2 = findSenior!(myfunc,int)(list); assert( senior_list2 == [-7, -9, 32]);
dlang函數內部的函數
//function in function int[] outfunction(int[] input,int z){ bool infunction(int x){ return x >= z; } static int zz = 30; static bool infunction2(int x){ return x > zz; } return findSenior!(infunction2)(input); }
dlang的閉包。下面的閉包裏面局部變量x在傳參後能夠保持不變。
//closure function T[] delegate(T[])finder(T)(T x) if(is(typeof(x == x) == bool)) { return delegate(T[] a){ return findListG(a,x);}; } auto delegate_func = finder(5); auto delegate_func_new = finder("ho"); //senior function test auto senior_list = [22,3,12,-7,-9,32]; int z = 30; assert(delegate_func([1,2,3,4,5,6]) == [5,6]); assert(delegate_func_new(["hi","ho","wo"]) == ["ho","wo"]);
dlang的同構可變函數採用 value...定義。簡單說就是結構相同,參數個數能夠變化
double average(double[] values...){ writeln("in value..."); if(values.empty){ throw new Exception("values is zero"); } return reduce!((a,b){return a+b;})(0.0,values)/values.length; } double average(double[] values){ writeln("in no value ..."); if(values.empty){ throw new Exception("values is zero"); } return reduce!((a,b){return a+b;})(0.0,values)/values.length; } double[] double_v = [1,2]; assert(average(double_v) == 1.5 ); assert(average(1,2) == 1.5); assert(average(1.1,2.1) == 1.6);
結構不一樣內容也不一樣的函數
void writeln_m(T...)(T args){ foreach(arg;args){ stdout.rawWrite(to!string(arg)); } stdout.rawWrite("\n"); stdout.flush(); foreach(k,v;args){ writeln(k,":",typeid(T[k]),"~~",v); } } writeln_m(1,2,1.1,"hell",[1,23]);
dlang中的元組。元組主要用來打包函數參數能夠讓可變參數任意的傳遞
Tuple!(int,double) tuple_v = tuple(1,1.2); void fun(T...)(T args){ //writeln(typeof(args).stringof); gun(tuple(args)); } void gun(T)(T value){ writeln(value.expand); }
pure參數修飾的純函數,只依賴本身的參數或者其餘純函數的函數
pure int mypure(int x){ //writeln(x); //error return x+10; }
不拋出異常的函數
nothrow void tryThrow(){ try{ throw new Exception("catch Exception"); }catch{ //writeln("has catch!");//error } }