阿里:有益的d技术

作者:土耳其的阿里.
d搞工程:漏洞少,生产力高,有趣.主观上,d造就更好的工程师:少了些完美主义,更实用,增长知识(@nogc对比pure),更少的规则(d:原型+生产力,可塑性).
内在单元测试:简单(仅提供断定,断定抛),无依赖,.
静如条件编译,区间.优势有:懒求值,最小内存,组件编程,管道编程,减少循环,等等.

5.iota.map!foo;//前面为区间,后面为算法.

只是返回单元素(如查找),及分割返回迭代器时,程序员得自己造区间.
每25行格式串字面量.而基于dip1036可能会格式成:

格式!(i"你好,$名,今天是$天");

用特殊命令行运行:程序 --DRT-gcopt=profile:1,来查看gc情况.用--profile=gc开关运行你程序.
减少分配内存:1,移除循环内分配.2,重用相同数组.3,用静 附加器.静 附加器是线程本地,但不可重入.
d的各种生产力特征.
区间格式限定器:

5.iota.writefln("%(%s%)");//打印01234

%(打开限定器,%)结束限定器.里面为每个元素如上面的%s.在元素限定器后是元素分配符.

5.iota.writefln("%(%s,%)");//打印0,1,2,3,4
//注意,没有尾巴逗号
5.iota.writefln("%(<%s>\n%)");//最后1个出问题,
//多了,要出问题
5.iota.writefln("%(<%s>%|\n%)");//最后1个出问题,

%|来表示实际的分隔符开始.
默认,""表示串,''表示符.

["今天","明天"].writefln!("%(%s,%)");
//打印时,默认包含"".
["今天","明天"].writefln!("%-(%s,%)");
//这样就光打印出`今天,明天`了.不含`""`.

还可嵌套,真吓人:

5.iota.map!(i=>i.iota).writefln!"%(%(%s,%)\n%)";

关联数组,第1个表,第2个表.

动 a=["a":"一","b":"二"];
a.writefln!"%-(%s是%s\n%)";

%10进制分隔符,默认3个1组,逗号分开.

writefln!"%,s"(123456789);//打印123,456,789;
writefln!"%,*s"(6,123456789);//打印123,456789;
writefln!"%,?s"('-',123456789);//打印123-456-789;
writefln!"%,*?s"(2,'-',123456789);//打印1-23-45-67-89;

并行,是d最有意思的事.如下:

每一(p;元素){
}//单核4秒
每一(p;元素.并行){
}//4核1秒

标.并行.并行,印象深刻是因为并行不是语言特征.
而是:返回对象的函数,定义了op应用来支持每一迭代,然后分发循环体至线程池,并等待他们完成.
同时,文档指南却只是要求循环体对每个元素独立,不互相干涉.只要注意到一个循环体由一个线程执行就是了.
两个配置要点:1,线程数匹配总核数.2,工作单元大小,默认为100个元素,如:

动 t=新 线程池(总核数/2);
每一(e;t.并行(元素,1)){//1(对任务重的元素),工作单元大小
    ...
}
t.完成();//不要忘记了.

根据情况,自己调整.
标.并发.
消息传递的并发,对许多程序是正确的并发类型.但比并行更复杂.

动 ws=4.iota.map!(i=>产生链接(&工)).数组;
空 工(){
    ...
}

产生链接来启动线程.用发送发送消息,用接收/接收超时来等待消息.用终止链接来检测线程终止.

整 完成=0;
当(完成<ws.长度){
    接收((常(终止链接)m){
        完成++;
    },
    //...
    );
}

还有终止所有者.线程有独立的函数调用栈.每个工作者必须抓并同异常通信.异常:可恢复的错误.
接收时报告异常.主线程可以抓,报告,中止.可在线程间共享数据.

动 ws=4.iota.map!(i=>产生链接(&工,转换(共享)新 整[42])).数组;
空 工(共享(整[])d){//取共享数据
    试{
        工实现(转换(整[])d);//去掉共享.
    }//...
}
空 工实现(整[]d){//非共享
    ...
}
//实际中不要这样!.也不知道作者在说什么.

嵌套函数.用于减少代码及提高可读性,也可懒执行.
未知类型声明.可用的型(f())来处理.
初化不可变变量.但将变量的初化逻辑放入λ,然后常 a={初化逻辑}();就可以了.
类型标志,而不是,主要是为了维护性.

空 f(标志!"压缩" c,标志!"跳过" s){
    ...
}
f(是.压缩,否.跳过);
f(是.跳过,否.压缩);//编译不过,这是好的.

可以这样传递变量:

动 到标志(别名 变量)(){
    枚 s=变量.的串;
    插件("中 变量?是."~s~":否."~s~";");
}
极 压缩;
极 跳过;
f(到标志!压缩,到标志!跳过);

模块作为单件对象.

//假定*函数
空 f(整[]a,串[]s){
    //调用一堆其他函数
}
//假定引入新变量
空 f(整[]a,串[]s,标志!"详细"x){
    //调用一堆其他函数
}

现在,一堆其他函数都要改签名,加上新变量.然而我们可以:

标志!"详细"v;
空 f(整[]a,串[]s,标志!"详细"x){
    .v=x;
    //调用一堆其他函数
}
//其他函数就不用改签名了.

漏洞:仅影响本线程,让其影响整个程序.则加上共享如下:

共享 标志!"详细"v;

小心.多次调用f可能出问题,
编译时解析文件.先写一个解析函数.然后:

不变 l=解析(导入("名"));

这里导入是编译时读文件.也可以用静 常/枚来替换不变.
结论:d是有效的工程工具,生产力高且有趣!.

上一篇:go常量,变量


下一篇:聊一聊GO中的变量、常量以及枚举