[D语言] DMD 0.168发布

新特性:
1、给委托增加ptr属性,指向委托所绑定的对象。
这是一个语法糖,dg.ptr被转化为cast(void*)dg,它只能作右值,所以除了能读取它以外,在语法上禁止对它赋值。要想把委托绑定到不同的对象,你只能自己实现:

class  Foo{
    
int  foo;
public :
    
this ( int  foo){
        
this .foo  =  foo;
    }

    
void  bar(){
        writefln(foo);
    }
}

void  main(){

    alias 
void   delegate () DG;
    DG dg 
=   & ( new  Foo( 1 )).bar;

    Foo[
10 ] foos;
    
foreach ( int  i, inout Foo foo; foos){
        foo 
=   new  Foo(i);
    }

    
void **  ptr  =  cast( void ** ) & dg;
    
foreach (Foo foo; foos){
        
* ptr  =  cast( void * )foo;
        dg();
    }
}

这种方式也不是我们所希望的,一般来说委托绑定到多个对象时,因为是取到某成员函数指针,再进行绑定。比如模拟一个ActiveSupport所扩展的一个ruby.Array#map用法:

import std.stdio;

class  Foo{
    
int  foo;
public :
    
this ( int  foo){
        
this .foo  =  foo;
    }

    
void  bar(){
        writefln(foo);
    }
}

class  Array(T){
    
private :
    T[] data;

    
public :
    
this (T[] data){
        
this .data  =  data[ 0  .. length];
    }

    
void  map( void  function() func){
        
void   delegate () dg;
        
void **  funcPtr  =  cast( void ** ) & dg  +   1 ;
        
* funcPtr  =  func;
        
void   **  ptr  =  cast( void ** ) & dg;
        
foreach (T v; data){
            
* ptr  =  cast( void * )v;
            dg();
        }
    }
}

void  main(){
    auto arr 
=   new  Array ! (Foo)([ new  Foo( 1 ),  new  Foo( 2 ),  new  Foo( 3 )]);
    arr.map(
& Foo.bar);
}

是的,delegate内部保存了2个指针,所以我们可以容易地hack它。

[注:上面的main函数中数组直接量赋给栈对象也是这个版本中新增的内容,显然只能用于static对象是很鸡肋的。这里简单带过不提。]

[注:上面这个map的模拟并不是ActiveSupport的map扩展的全部用途,那个map还是收集返回值,这里只演示调用语法。ActiveSupport中扩展的map调用语法是map(&:to_s),就可以收集到数组中所有元素调用to_s后的返回值。]

2、给内嵌内的实例增加outer属性,指向外层对象。

import std.stdio;

class  Outer{
    
class  Inner{}

    
this (){
        Inner inner 
=   new  Inner;
        inner.outer.foo();
    }

    
void  foo(){
        writefln(
" foo " );
    }
}

void  main(){
    Outer outer 
=   new  Outer;
}

这个特性可能应用并不是很广吧。

3、mixin多个析构函数。

template A(){
    
this (){
    }
    
~ this (){
        writefln(
" A::~A() " );
    }
}

template B(){
    
~ this (){
        writefln(
" B::~B() " );
    }
}

class  C{
    mixin A;
    mixin B;
}

void  main(){
    C c 
=   new  C;
    delete c;
}

这些析构函数会和mixin相反的顺序执行。我不明白的是,为什么不让mixin多个构造函数?为何不让这些构造函数晚于被mixin的类(上面的C类)的构造函数,并按mixin进来的顺序执行?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值