D語言之函數

參考自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
	}
}
相關文章
相關標籤/搜索