作者:土耳其的阿里
.
用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是有效的工程工具,生产力高且有趣!
.