这一版本在强大的民意压力之下取消了上一版的“隐式转换表达式为委托”这一特性,取而代之的是一个lazy关键字。
取消的理由是这个转换太隐晦了,最好是显式地标示出这种转换,所以引入一个lazy关键字。D语言还在发展中,很多特性都在尝试,这种修改也不是第一次了。
首先看看这个lazy。
上一版实现了这样一个特性:
log的参数被隐式转化为一个委托,这样只有用到这个值的时候才真正求值。
由于这种隐式转化很容易形成陷阱,所以这一版改为一个lazy关键字,看起来要简洁一些了:
log函数中使用msg这个变量就会调用那个隐式的委托,要注意的是每次取msg的值都会执行这个委托,所以我觉得这个陷阱更大了,当然它把陷阱丢给编写代码的人,而不是使用代码的人,所以好坏还无从分辨。
下面这点代码可以演示这个小陷阱:
看起来bar好像会执行一次,实际上这段代码会打印出3行"Call bar()",原来使用委托还可以看到一个显式的函数调用呢。
另一个member templates特性未见到文档,猜想大概是支持成员函数模板吧。
取消的理由是这个转换太隐晦了,最好是显式地标示出这种转换,所以引入一个lazy关键字。D语言还在发展中,很多特性都在尝试,这种修改也不是第一次了。
首先看看这个lazy。
上一版实现了这样一个特性:
void
log(
char
[]
delegate
() msg){
writefln(msg());
}
log( " Hello, " ~ " Li Jie! \n " ~ " Welcome! " );
writefln(msg());
}
log( " Hello, " ~ " Li Jie! \n " ~ " Welcome! " );
log的参数被隐式转化为一个委托,这样只有用到这个值的时候才真正求值。
由于这种隐式转化很容易形成陷阱,所以这一版改为一个lazy关键字,看起来要简洁一些了:
void
log(lazy
char
[] msg){
writefln(msg);
}
log( " Hello, " ~ " Li Jie! \n " ~ " Welcome! " );
writefln(msg);
}
log( " Hello, " ~ " Li Jie! \n " ~ " Welcome! " );
log函数中使用msg这个变量就会调用那个隐式的委托,要注意的是每次取msg的值都会执行这个委托,所以我觉得这个陷阱更大了,当然它把陷阱丢给编写代码的人,而不是使用代码的人,所以好坏还无从分辨。
下面这点代码可以演示这个小陷阱:
void
foo(lazy
int
a){
int b = a + 1 ;
int c = a * 3 ;
int d = a / 2 ;
}
int bar(){
writefln( " Call bar() " );
return 12 ;
}
foo(bar());
int b = a + 1 ;
int c = a * 3 ;
int d = a / 2 ;
}
int bar(){
writefln( " Call bar() " );
return 12 ;
}
foo(bar());
看起来bar好像会执行一次,实际上这段代码会打印出3行"Call bar()",原来使用委托还可以看到一个显式的函数调用呢。
另一个member templates特性未见到文档,猜想大概是支持成员函数模板吧。