﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-qiezi的学习园地-随笔分类-D</title><link>http://www.cppblog.com/cpunion/category/320.html</link><description>AS/C/C++/D/Java/JS/Python/Ruby</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 13:00:17 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 13:00:17 GMT</pubDate><ttl>60</ttl><item><title>[D语言] D语言数组</title><link>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 07 Oct 2006 08:21:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/13418.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/13418.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/13418.html</trackback:ping><description><![CDATA[先看一段代码：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">];<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    c.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br /><br />它输出结果如下：<br /><br />B7D19FB0, B7D19FB4, B7D19FB8,<br />B7D19FB0, B7D19FB4,<br />B7D19FB0, B7D19FB4, B7D19FB8,<br />B7D1CFA0, B7D1CFA4, B7D1CFA8, B7D1CFAC,<br /><br />可以看到前3行地址相同，后面一行地址不同。为什么？<br /><br />D语言的数组分配是内存紧凑的，当减小数组长度减小时，只需要修改切片大小而不需要重新分配。当长度变大时，也会检查原来的缓冲区是否够大，以确定是否需要重新分配空间。注意第2次操作时把长度恢复为原来大小时，并非真的恢复了原来的状态，后面长出来的元素会被初始化为默认值。<br /><br />再来看一个：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">];<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] d </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> c;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    d.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    d.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">;<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; c){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(inout </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; d){<br />        writef(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">i);<br />        writef(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    writefln(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br />}</span></div><br />在执行int[] d = c;以后，d的确是和c共享了存储区。不过在改变d的长度以后，它就和c分道扬镳了。所以int[] d = c不能理解为d是一个指向c的引用，它实际上创建了一个新的数组对象，但并不拷贝数组元素，它和int[] d = c[0 .. length]是等价的，都是数组切片操作。<br /><br />这个问题让我困惑不已。比如你用char[]表示一个单词，用char[][]表示一行，char[][][]表示多行。如何引用这个单词？你当然可以每次使用lines[i][j]，但如果处理步骤很多，这会不会看起来很头大？<br /><br />看上去应该这样使用：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][][] lines;<br /></span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][] line </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> lines[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">];<br />line.length </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> line.length </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />line[length </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;</span></div><br />可惜根据前面的结论，这将无法影响到lines。如果找不到一个引用类型指向数组，有时候使用起来还真是很麻烦。看起来把Line/Word包装成类是个勉强凑合的主意。。。<img src ="http://www.cppblog.com/cpunion/aggbug/13418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-07 16:21 <a href="http://www.cppblog.com/cpunion/archive/2006/10/07/13418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] Array slicing</title><link>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 06 Oct 2006 01:35:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/13393.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/13393.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/13393.html</trackback:ping><description><![CDATA[数组slicing操作并不复制数据。<br /><br />指针的slicing操作和数组slicing语意是相同的。<br /><br />通过slicing生成D数组，比原来直接使用指针的好处是可以有边界检查。<br /><br />最近刚好犯了这个错误，在使用freetype时，render出来的位图数据直接使用slicing生成数组保存起来。由于slicing并不复制数据，这样后面的render操作会覆盖前面的数据，所以我保存的数组其实都指向同一个缓冲区。当释放face对象时，缓冲区也没了，再访问恐怕要段错误了。<br /><br />这个是D文档中明确描述了的，我却花了点时间才排除这个错误，写下来记录之～<br /><img src ="http://www.cppblog.com/cpunion/aggbug/13393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-06 09:35 <a href="http://www.cppblog.com/cpunion/archive/2006/10/06/13393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.168发布</title><link>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 05 Oct 2006 01:23:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/13362.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/13362.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/13362.html</trackback:ping><description><![CDATA[新特性：<br />1、给委托增加ptr属性，指向委托所绑定的对象。<br />这是一个语法糖，dg.ptr被转化为cast(void*)dg，它只能作右值，所以除了能读取它以外，在语法上禁止对它赋值。要想把委托绑定到不同的对象，你只能自己实现：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Foo{<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo;<br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> foo;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> bar(){<br />        writefln(foo);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br /><br />    alias </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() DG;<br />    DG dg </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)).bar;<br /><br />    Foo[</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">] foos;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i, inout Foo foo; foos){<br />        foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(i);<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg;<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(Foo foo; foos){<br />        </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)foo;<br />        dg();<br />    }<br />}</span></div><br />这种方式也不是我们所希望的，一般来说委托绑定到多个对象时，因为是取到某成员函数指针，再进行绑定。比如模拟一个ActiveSupport所扩展的一个ruby.Array#map用法：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">import std.stdio;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Foo{<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo;<br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> foo){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.foo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> foo;<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> bar(){<br />        writefln(foo);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Array(T){<br />    </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br />    T[] data;<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(T[] data){<br />        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.data </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> data[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> .. length];<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> map(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> function() func){<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() dg;<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> funcPtr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />        </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">funcPtr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> func;<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);"> ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">dg;<br />        </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(T v; data){<br />            </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">ptr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)v;<br />            dg();<br />        }<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    auto arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Array</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">(Foo)([</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">), </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Foo(</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">)]);<br />    arr.map(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">Foo.bar);<br />}</span></div><br />是的，delegate内部保存了2个指针，所以我们可以容易地hack它。<br /><br />[注：上面的main函数中数组直接量赋给栈对象也是这个版本中新增的内容，显然只能用于static对象是很鸡肋的。这里简单带过不提。]<br /><br />[注：上面这个map的模拟并不是ActiveSupport的map扩展的全部用途，那个map还是收集返回值，这里只演示调用语法。ActiveSupport中扩展的map调用语法是map(&amp;:to_s)，就可以收集到数组中所有元素调用to_s后的返回值。]<br /><br />2、给内嵌内的实例增加outer属性，指向外层对象。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">import std.stdio;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Outer{<br />    </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Inner{}<br /><br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        Inner inner </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Inner;<br />        inner.outer.foo();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> foo(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">foo</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    Outer outer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Outer;<br />}</span></div><br />这个特性可能应用并不是很广吧。<br /><br />3、mixin多个析构函数。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">template A(){<br />    </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />    }<br />    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">A::~A()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br />template B(){<br />    </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">(){<br />        writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">B::~B()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> C{<br />    mixin A;<br />    mixin B;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(){<br />    C c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> C;<br />    delete c;<br />}</span></div><br />这些析构函数会和mixin相反的顺序执行。我不明白的是，为什么不让mixin多个构造函数？为何不让这些构造函数晚于被mixin的类（上面的C类）的构造函数，并按mixin进来的顺序执行？<br /><img src ="http://www.cppblog.com/cpunion/aggbug/13362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-10-05 09:23 <a href="http://www.cppblog.com/cpunion/archive/2006/10/05/13362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.167发布</title><link>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 19 Sep 2006 12:16:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/12721.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/12721.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/12721.html</trackback:ping><description><![CDATA[这个版本实现了计划已久的数组直接量。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />void main(){<br />  {<br />    static </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />  {<br />    static float[] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [1f</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />  {<br />    static char[][] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">1</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">2</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">3</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">4</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">5</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">];<br />    writefln(typeid(typeof(arr[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])));<br />    writefln(arr);<br />  }<br />}</span></div><br />数组类型由第1个元素类型决定，类型不匹配将会产生编译错误。<br /><br />接着是多维数组：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />void main(){<br />  static </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[][] arr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> [[</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">7</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">]];<br />  </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[] </span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);">; arr){<br />    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i; </span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);">){<br />      writefln(i);<br />    }<br />  }<br />}</span></div><br /><br />另一个特性是更强的typedef。原有的typedef强类型在某些情况下会产生混乱。<br /><br />下面的代码摘自 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&amp;group=digitalmars.D.bugs&amp;artnum=3843<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /><br />typedef </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Int1;<br />typedef </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> Int2;<br /><br />void show(Int1 v) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Int1: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> v);<br />}<br /><br />void show(Int2 v) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Int2: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> v);<br />}<br /><br />void show(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">int: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> i);<br />}<br /><br />void show(long l) {<br />     writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">long: %d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> l);<br />}<br /><br />void main() {<br />     Int1 value1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">42</span><span style="color: rgb(0, 0, 0);">;<br />     Int2 value2 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">69</span><span style="color: rgb(0, 0, 0);">;<br /><br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> value2);<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />     show(</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br /><br />     long l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">23</span><span style="color: rgb(0, 0, 0);">;<br />     show(value1 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> l);<br />     show(l </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value2);<br /><br />     short s </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">105</span><span style="color: rgb(0, 0, 0);">;<br />     show(s </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> value1);<br />     show(value2 </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> s);<br />}</span></div><br />如上面代码所示。typedef定义出来的类型和原有类型的相同形式重载函数可以共存，这可以完成更强类型的重载，C＋＋的重载还不能实现这个。<br /><br />这个强类型的typedef好像原本就支持，大概是运算结果类型比较模糊。<br /><br />好处是显页易见的。比如有一个Time和TimeInterval类型，它用来表示绝对时间或相对时间间隔；另有一个输出函数用来显示结果。<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">stdio;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> std</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">string;<br /><br />typedef long </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">;<br />typedef long TimeInterval;<br /><br />void output(</span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> t){<br />  writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Time: </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> toString(cast(long)t));<br />}<br />void output(TimeInterval t){<br />  writefln(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Interval: </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> toString(cast(long)t));<br />}<br />void main(){<br />  </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(</span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(128, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">;<br />  TimeInterval interval </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cast(TimeInterval)</span><span style="color: rgb(128, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">;<br />  output(</span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);">);<br />  output(interval);<br />}</span></div><br />是的，使用上麻烦了很多，因为我们试图用一个数值类型去表示多个矢量类型。<br /><br />这里Time time = cast(Time)100不再只是100这个简单的数值，它还携带了Time这个类型。TimeInterval interval = cast(TimeInterval)100也不只是100这个数值，我们给它赋予了时间间隔的含义。<br /><br />还可以想像得更开阔一些，用它定义时间、长度、面积、加速度、速度、温度等，重载一些计算函数（可惜D还不支持全局操作符重载），这样就方便完成一些物理量的运算了，而且类型得到检查，速度加一个整数值结果还是速度，速度乘时间得到的是长度，时间减时间得到的是时间间隔，速度加时间将产生编译错误。。。。。。神奇的是这些类型可能都是一些简单类型，我相信它至少可以保证运行效率不会太低。当然你用C＋＋类也可以完成这些，并且利用编译器优化让它的效率保持最高，甚至内联的结果就是简单类型的运算，我还是更愿意使用这简单的类型来typedef。当然这可能需要写大量重复的函数重载形式，没有关系，我想使用模板和mixin应该可以简化这一过程，而且会有相当多的家伙们愿意使用这种麻烦的形式来获得更“正确”的编译检查。<br /><br /><br />所以说，D语言的typedef的意义其实就是实现了矢量类型。<br /><br /><hr size="2" width="100%" /><br />又多想了一点。<br /><br />强类型要，语法糖也应该要。是不是可以借鉴一下ruby的语法，实现这种调用呢？<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">Length</span><span style="color: rgb(0, 0, 0);"> l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">cm;<br />l </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">m;<br /></span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);"> t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">now;<br />TimeInterval i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">hours;</span></div><br />免去了一些初始化的麻烦。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/12721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-19 20:16 <a href="http://www.cppblog.com/cpunion/archive/2006/09/19/12721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.166发布</title><link>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 01 Sep 2006 14:34:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/11938.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/11938.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/11938.html</trackback:ping><description><![CDATA[这一版本在强大的民意压力之下取消了上一版的“隐式转换表达式为委托”这一特性，取而代之的是一个lazy关键字。<br /><br />取消的理由是这个转换太隐晦了，最好是显式地标示出这种转换，所以引入一个lazy关键字。D语言还在发展中，很多特性都在尝试，这种修改也不是第一次了。<br /><br />首先看看这个lazy。<br /><br />上一版实现了这样一个特性：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> log(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[] </span><span style="color: rgb(0, 0, 255);">delegate</span><span style="color: rgb(0, 0, 0);">() msg){<br />  writefln(msg());<br />}<br /><br />log(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Li Jie! \n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Welcome!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);</span></div><br />log的参数被隐式转化为一个委托，这样只有用到这个值的时候才真正求值。<br /><br />由于这种隐式转化很容易形成陷阱，所以这一版改为一个lazy关键字，看起来要简洁一些了：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> log(lazy </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[]  msg){<br />  writefln(msg);<br />}<br /><br />log(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Li Jie! \n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">~</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Welcome!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);</span></div><br />log函数中使用msg这个变量就会调用那个隐式的委托，要注意的是每次取msg的值都会执行这个委托，所以我觉得这个陷阱更大了，当然它把陷阱丢给编写代码的人，而不是使用代码的人，所以好坏还无从分辨。<br /><br />下面这点代码可以演示这个小陷阱：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> foo(lazy </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a){<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> c </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">;<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> d </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> bar(){<br />  writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Call bar()</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />  </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">12</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br />foo(bar());</span></div><br />看起来bar好像会执行一次，实际上这段代码会打印出3行"Call bar()"，原来使用委托还可以看到一个显式的函数调用呢。<br /><br />另一个member templates特性未见到文档，猜想大概是支持成员函数模板吧。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/11938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-09-01 22:34 <a href="http://www.cppblog.com/cpunion/archive/2006/09/01/11938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] DMD 0.165发布</title><link>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 21 Aug 2006 05:24:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/11517.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/11517.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/11517.html</trackback:ping><description><![CDATA[前几个版本主要是修正BUG，并没有多少新特性，这个版本终于增加了一个“隐式转换表达式到委托”，这个特性也使“懒惰(或延迟)求值”成为可能。<br /><br />详细信息可见：<a href="http://www.digitalmars.com/d/lazy-evaluation.html">http://www.digitalmars.com/d/lazy-evaluation.html</a><br /><br />它首先解决了一个存在于java中的日志问题，java里面一个写日志标准格式如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (log.isLoggable(Level.INFO)) {<br />  log.info(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">aaaa</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}</span></div><br />因为log.info的参数求值可能影响性能，所以使用这种繁琐的方式来降低关闭日志时的性能开销。<br /><br />C/C++使用宏来解决这个问题，唯一的问题是修改日志级别会导致项目必须重编译。<br /><br />[注：指的是用宏来定义日志级别的方式，使用其它动态修改日志级别的方式对性能要求很高的项目来说可能不可接受]<br /><br />D语言使用另一种方式来解决，首先要用到“表达式到委托的隐式转换”，下面是委托作为参数时的使用方法：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo( </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] (){<br />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br />  }<br />);</span></div><br />因为这个委托并不需要参数，而返回值可以推导，所以在早先的一个版本里，D允许我们简化这个过程：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo({</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;});</span></div><br />DMD 0.165允许我们更进一步：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> foo(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg){<br />  writefln(dg());<br />}<br /><br />foo(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, World</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div><br />这个字符串参数会被隐式转换成一个委托。<br /><br />现在可以用一样的方法处理日志，在没有宏的系统中，日志函数一般格式如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> log(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] message)<br />{<br />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (logging)<br />    fwritefln(logfile, message);<br />}</span></div><br />为了让它使用懒惰求值这个特性，这里把这个函数的参数改为委托：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> log(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] </span><span style="COLOR: #0000ff">delegate</span><span style="COLOR: #000000">() dg)<br />{<br />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (logging)<br />    fwritefln(logfile, dg());<br />}</span></div><br />从上面提到的内容我们知道使用它也很简单：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">log(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">My name is </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Li Jie</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span></div><br />这个参数的求值就是在log函数里面完成的。<br /><br />当然委托会增加一些开销，在上面这个例子中，这个开销是在日志打开时执行委托所带来的，它增加了一次委托调用的开销，不过好在打开日志功能时，其它方面的开销远大过委托调用。关闭日志时，它不会带来开销，它只是把字符串指针压栈改为委托指针压栈。<img src ="http://www.cppblog.com/cpunion/aggbug/11517.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-21 13:24 <a href="http://www.cppblog.com/cpunion/archive/2006/08/21/11517.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[D语言] 用D语言编写Ruby扩展</title><link>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 18 Aug 2006 22:17:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/11427.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/11427.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/11427.html</trackback:ping><description><![CDATA[<p>Ruby语言的官方解释程序是使用C语言开发的，一般用C语言来编写扩展。D语言和C语言是二进制兼容的，所以可以使用D语言编写Ruby扩展。<br /></p>
		<p>
				<strong>
						<br />一、移植C库到D的一般过程</strong>
		</p>
		<p>C使用头文件来处理符号依赖，在D里面链接外部库文件时，要使用extern (C)声明来引入符号，这是一个转换过程。</p>
		<p>如何转换一个C头文件到D文件？D文档的htomodule.html有详尽说明。一般的转换过程如下：
</p>
		<p>1、运行预处理程序处理掉头文件里面的宏。</p>
		<p>2、删除经过预处理以后的多余信息。由于C的头文件包含，每个头文件经过预处理以后都会包含一些重复内容，我们需要剔除这部分内容，通过查找行号即可完成。</p>
		<p>3、转换相应声明到D声明，这一步可以使用一个c2h程序来完成。</p>
		<p>注意预处理程序处理完毕以后，宏函数以及宏定义的常量会被去除，这可能不是你想要的，所以最好的办法可能是手工转换。</p>
		<p>另一种调用是在D里面调用动态链接库，这需要你使用implib工具从动态链接库产生一个.lib导入库文件，然后生成D声明，再编译链接即可。如果是在linux下使用共享库，则只需要编写D声明文件，然后直接链接即可。<br /></p>
		<p>
				<strong>
						<br />二、调用C库</strong>
		</p>
		<p>转换完毕以后，就可以调用了。如果你只是要测试一下，就可以只声明使用过的外部函数、变量即可。</p>
		<p>例如我们要编写Programming Ruby里面的一个Ruby Extension例子，相应的D代码如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> test.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module test;<br /><br />import ruby;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br />VALUE t_init(VALUE self)<br />{<br />  VALUE arr </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_ary_new();<br />  rb_iv_set(self, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">@arr</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, arr);<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> self;<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br />VALUE t_add(VALUE self, VALUE anObject)<br />{<br />  VALUE arr </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_iv_get(self, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">@arr</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">);<br />  rb_ary_push(arr, anObject);<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> arr;<br />}<br /><br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C){<br /><br />VALUE cTest;<br /><br />alias VALUE(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">func_type)();<br /><br />export </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> Init_Test()<br />{<br />  cTest </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> rb_define_class(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">Test</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, rb_cObject);<br />  rb_define_method(cTest, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">initialize</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, cast(func_type)</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">t_init, </span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">);<br />  rb_define_method(cTest, </span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">add</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">, cast(func_type)</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">t_add, </span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">);<br />}<br /><br />}  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> extern(C)</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">
						<br />
				</span>
		</div>
		<p>
				<br />和C代码很相似。由于我们只使用了几个外部函数、变量，所以只需要声明这几个符号即可：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> ruby.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module ruby;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> (C){<br />    alias </span>
				<span style="COLOR: #0000ff">ulong</span>
				<span style="COLOR: #000000"> VALUE;<br />    VALUE rb_cObject;<br />    VALUE rb_ary_new ();<br />    VALUE rb_ary_push (VALUE, VALUE);<br />    VALUE rb_iv_set (VALUE,  </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">, VALUE);<br />    VALUE rb_iv_get (VALUE,  </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">);<br />    VALUE rb_define_class ( </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">,VALUE);<br />    </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> rb_define_method (VALUE, </span>
				<span style="COLOR: #0000ff">char</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">,VALUE(</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">)(),</span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000">);<br />}<br /></span>
		</div>
		<p>
				<strong>
						<br />三、生成动态链接库(Windows DLL)或共享库(Linux so文件)</strong>
		</p>
		<p>D语言在Windows上编写DLL，除了要有D源文件以外，还要有DLL定义文件：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> test.def</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">LIBRARY         Test<br />DESCRIPTION     </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">Test written in D</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">
						<br />
						<br />EXETYPE  NT<br />CODE            PRELOAD DISCARDABLE<br />DATA            PRELOAD SINGLE<br /></span>
		</div>
		<p>这是一个通用的格式，只是一些描述信息，因为D中可以使用export关键字导出符号，所以不需要在这里声明导出函数，只有在编写COM DLL时才会增加其它一些信息。</p>
		<p>另外由于D语言要初始化GC以及其它一些信息，所以还需要在DllMain里面调用初始化及终止代码。由于不同平台的初始化过程不完全相同，这里我简单封闭了一下不同平台的初始化代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/library.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module os.library;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C){<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> gc_init();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> gc_term();<br />  version(Windows) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _minit();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleCtor();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleDtor();<br />  </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _moduleUnitTests();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STI_monitor_staticctor();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STI_critical_init();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STD_monitor_staticdtor();<br />  version(linux) </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> _STD_critical_term();<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_init()<br />{<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("Start init D runtime");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">  version(linux) _STI_monitor_staticctor();<br />  version(linux) _STI_critical_init();<br />  gc_init();<br />  version(Windows) _minit();<br />  _moduleCtor();<br />  _moduleUnitTests();<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("init finished");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">}<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000">(C)<br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_fini()<br />{<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("Start term D runtime");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">  _moduleDtor();<br />  gc_term();<br />  version(linux) _STD_critical_term();<br />  version(linux) _STD_monitor_staticdtor();<br />  </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> writefln("term finished");</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">}<br /></span>
		</div>
		<p>现在可以为Windows编写初始化及终止代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/dll.d</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">module os.dll;<br /><br /></span>
				<span style="COLOR: #0000ff">private</span>
				<span style="COLOR: #000000"> import os.library;<br /></span>
				<span style="COLOR: #0000ff">private</span>
				<span style="COLOR: #000000"> import std.c.windows.windows;<br /><br />HINSTANCE g_hInst;<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> (Windows)<br />BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)<br />{<br />  </span>
				<span style="COLOR: #0000ff">switch</span>
				<span style="COLOR: #000000"> (ulReason)<br />  {<br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_PROCESS_ATTACH:<br />      d_init();<br />      </span>
				<span style="COLOR: #0000ff">break</span>
				<span style="COLOR: #000000">;<br /><br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_PROCESS_DETACH:<br />      d_fini();<br />      </span>
				<span style="COLOR: #0000ff">break</span>
				<span style="COLOR: #000000">;<br /><br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_THREAD_ATTACH:<br />    </span>
				<span style="COLOR: #0000ff">case</span>
				<span style="COLOR: #000000"> DLL_THREAD_DETACH:<br />      </span>
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> Multiple threads not supported yet</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">      </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">false</span>
				<span style="COLOR: #000000">;<br />  }<br />  g_hInst</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">hInstance;<br />  </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">true</span>
				<span style="COLOR: #000000">;<br />}<br /></span>
		</div>
		<p>由于Linux共享库并没有标准的入口函数(或是我不知道它)，这里使用gcc扩展的初始、终止代码，不过是以C语言实现的：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #008000">//</span>
				<span style="COLOR: #008000"> os/so.c</span>
				<span style="COLOR: #008000">
						<br />
				</span>
				<span style="COLOR: #000000">#include </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #000000">ruby.h</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">static</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">) __attribute__((constructor));<br /></span>
				<span style="COLOR: #0000ff">static</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">) __attribute__((destructor));<br /><br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">);<br /></span>
				<span style="COLOR: #0000ff">extern</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> d_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">);<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_init(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">)<br />{<br />  d_init();<br />}<br /><br /></span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000"> so_fini(</span>
				<span style="COLOR: #0000ff">void</span>
				<span style="COLOR: #000000">)<br />{<br />  d_fini();<br />}<br /></span>
		</div>
		<p>现在可以尝试编译链接，在Linux上编译命令如下：<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">gcc </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">o os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.o </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">c os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.c </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">I </span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">usr</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">lib</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">ruby</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">1.8</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">i686</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">linux <br />gdc </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">o Test.so test.d os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">so.o ruby.d </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">shared </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">fPIC </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">lruby</span>
		</div>
		<p>你可以在irb下测试：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">require </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">Test</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">
						<br />test </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> Test.</span>
				<span style="COLOR: #0000ff">new</span>
				<span style="COLOR: #000000">
						<br />test.add(</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">)<br />test.add(</span>
				<span style="COLOR: #000000">2</span>
				<span style="COLOR: #000000">)<br />test.add(</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">a</span>
				<span style="COLOR: #000000">"</span>
				<span style="COLOR: #000000">)<br /></span>
		</div>
		<p>可以看到add总是返回一个array，与期望结果一致。</p>
		<p>使用gdc是因为dmd在linux上无法生成共享库。</p>
		<p>在Windows上的编译命令如下：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">dmd </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">oftest.dll test.d test.def ruby18.lib os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">dll.d os</span>
				<span style="COLOR: #000000">/</span>
				<span style="COLOR: #000000">library.d</span>
		</div>
		<p>ruby18.lib是使用implib从msvcrt-ruby18.dll导出的，这个编译过程很顺利，不过不幸的是它运行有一些问题，大概是一些初始值错误，我暂时还没有找到原因。或许也应该尝试一下gdc，不过我不知道如何从.DLL文件导出一个gdc支持的ELF格式的导入库文件。<br /></p>
		<p>
				<strong>四、项目打算</strong>
		</p>
		<p>打算建立一个rubyd项目，除了转换ruby头文件以外，还要作一些扩展，比如转换D类到ruby类，这方面已有借鉴，比如dsource.org上的pyd项目。</p>
		<p>由于以前在建立项目方面有过失败经历(asgard项目由于兴趣转移和其它原因比如语法丑陋等而未能进行)，这次还是保守一些，先完成D声明的转换，我已经使用工具转换了所有头文件，不过正如前面所说，宏函数和宏常量都丢失了，所以需要重新手工转换。<br /></p>
		<p>
				<strong>五、其它问题</strong>
		</p>
		<p>1、如何从.DLL文件导出一个gdc支持的ELF格式的导入库文件？<strong>如果你知道可以告诉我</strong>，先谢过了。</p>
		<p>2、dmd生成可执行文件问题不大，生成动态链接库或共享库有很大缺陷，特别是不能生成共享库，我可不想再找一个只能再Windows上正常运行的编译器。如何让它改进这些方面？</p>
		<p>3、gdc使用dmd前端和gcc后端，应该会成熟一些，不过一般会比dmd前端版本稍低，而且gdc发布版本不是很频繁，大概4-5个dmd版本才会有一个gdc版本(初略计算)，所以一些新特性不能够及时加入进来。</p><img src ="http://www.cppblog.com/cpunion/aggbug/11427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-08-19 06:17 <a href="http://www.cppblog.com/cpunion/archive/2006/08/19/11427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>COM接口IDL转换为D接口以及__uuidof实现。</title><link>http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 11 Apr 2006 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/5283.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/5283.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/5283.html</trackback:ping><description><![CDATA[D语言里面，可以通过version(Windows)来兼容COM接口，不过对于__uuidof却没有相应实现。<br /><br />原始COM接口定义类似这样（找个简单的）：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">[<br />    local,<br />    </span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">,<br />    uuid(594f31d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">7f19</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">11d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">b194</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">00a0c90dc8bf)<br />]<br /></span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> IRpcChannelBuffer2 : IRpcChannelBuffer<br />{<br /><br />    HRESULT GetProtocolVersion<br />    (<br />        [</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">] DWORD </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pdwVersion<br />    );<br />}</span></div><br />VC＋＋中可通过__uuidof操作符来获取COM接口中的uuid“元”信息。<br /><br />转换为D接口后代码如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">version(Windows) {<br /><br /></span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> IRpcChannelBuffer2 : IRpcChannelBuffer<br />{<br />    HRESULT GetProtocolVersion (DWORD</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pdwVersion);<br />}<br /><br />}</span></div><br />失去了uuid信息。只要稍作修改，在转换时保存uuid，即可以模板来模拟实现__uuidof操作符。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">import std.c.windows.com;<br />import std.</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">;<br />import std.stdio;<br /><br /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><br />template HexStrToUbyte(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexStrToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cast(ubyte)HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str);<br />}<br /><br />template HexStrToUshort(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ushort</span><span style="COLOR: #000000"> HexStrToUshort </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cast(</span><span style="COLOR: #0000ff">ushort</span><span style="COLOR: #000000">)HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str);<br />}<br /><br />template HexStrToUint(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">uint</span><span style="COLOR: #000000"> HexStrToUint </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cast(</span><span style="COLOR: #0000ff">uint</span><span style="COLOR: #000000">)HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str);<br />}<br /><br />template HexStrToUlong(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (str.length </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ulong</span><span style="COLOR: #000000"> HexStrToUlong </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> HexToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]);<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">ulong</span><span style="COLOR: #000000"> HexStrToUlong <br />            </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> HexToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">..length]) <br />              </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">16UL</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> HexStrToUlong</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..length</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]);<br />}<br /><br /></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br /><br />template HexToUbyte(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] c)<br />{<br />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">A</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xa</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">B</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xb</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xc</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">D</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">d</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xd</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">E</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">e</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xe</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">F</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">f</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xf</span><span style="COLOR: #000000">;<br />}<br /><br />template HexToUbyte_bug(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> c)<br />{<br />    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">&lt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">A</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">a</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xa</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">B</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">b</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xb</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">C</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xc</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">D</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">d</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xd</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">E</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">e</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xe</span><span style="COLOR: #000000">;<br />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">F</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">f</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br />        </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ubyte HexToUbyte1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0xf</span><span style="COLOR: #000000">;<br />}<br /><br />template IIDFromStr(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">[] str)<br />{<br />    </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> IID IIDFromStr </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {<br />        HexStrToUint</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">]),<br />        HexStrToUshort</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">]), <br />        HexStrToUshort</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">18</span><span style="COLOR: #000000">]),<br />        [<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">19</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">]), <br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">24</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">26</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">28</span><span style="COLOR: #000000">]), <br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">28</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">30</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">30</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">]), <br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">34</span><span style="COLOR: #000000">]),<br />          HexStrToUbyte</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(str[</span><span style="COLOR: #000000">34</span><span style="COLOR: #000000">..</span><span style="COLOR: #000000">36</span><span style="COLOR: #000000">])<br />        ]<br />    };<br />}<br /><br />template __uuidof(T:IUnknown)<br />{<br />    IID __uuidof </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> IIDFromStr</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">00000000-0000-0000-C000-000000000046</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}<br /><br />template __uuidof(T:IClassFactory)<br />{<br />    IID __uuidof </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> IIDFromStr</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><span style="COLOR: #000000">00000001-0000-0000-C000-000000000046</span></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}<br /><br /><br /></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> main()<br />{<br />    IID iu  </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __uuidof</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(IUnknown);<br />    IID icp </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> __uuidof</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(IClassFactory);<br /><br />    writefln(iu.Data1);<br />    writefln(iu.Data2);<br />    writefln(iu.Data3);<br />    writefln(iu.Data4);<br />}</span></div><br />如上面代码，接口在转换时，把：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><p><span style="COLOR: #000000">[<br />    local,<br />    </span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">,<br />    uuid(594f31d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">7f19</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">11d0</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">b194</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">00a0c90dc8bf)<br />]<br />interface IRpcChannelBuffer2 : IRpcChannelBuffer<br />{</span></p><p><span style="COLOR: #000000">    HRESULT GetProtocolVersion<br />    (<br />        [in,out] DWORD *pdwVersion<br />    );<br />}</span></p></div><br />转换为：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template __uuidof(T:IRpcChannelBuffer2)<br />{<br />    IID __uuidof </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> IIDFromStr</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">594f31d0-7f19-11d0-b194-00a0c90dc8bf</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />}<br />version (Windows) {<br /><br /></span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> IRpcChannelBuffer2 : IRpcChannelBuffer {<br />    HRESULT GetProtocolVersion (DWORD</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> pdwVersion);<br />}<br /><br />}</span></div><br />即可，这个可以交由自动化工具完成。<br /><br />由于__uuidof模板值在编译期决议，没有实际的运行期开销。<img src ="http://www.cppblog.com/cpunion/aggbug/5283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-04-11 14:26 <a href="http://www.cppblog.com/cpunion/archive/2006/04/11/5283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++/D/python性能一比</title><link>http://www.cppblog.com/cpunion/archive/2006/03/31/4840.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 31 Mar 2006 03:06:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/31/4840.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4840.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/31/4840.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4840.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4840.html</trackback:ping><description><![CDATA[实际上不是全面测试性能。应该这么说：使用一个你熟悉的语言，用它写出一个高效的版本（做下面那件事）。<br /><br />不小心读到一个帖子：http://blog.vckbase.com/jzhang/archive/2006/03/28/18807.html<br /><br />看到C＋＋竟然被比下去了，自然不是很舒服，毕竟C＋＋对于C并没有太大的性能上的降低，而python是C写的（指Cpython实现），自然不会高过C。（废话，C基本上接近汇编效率了）<br /><br />可惜C＋＋又很难找出这么高效的实现，STL效率还是低了些（为什么？一直以为它很高效，用得比较放心）。最近一直比较关注D语言，于是用D语言来测试一下。代码如下：<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">import std.stdio;<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">import std.</span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">import std.perf;<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[][] argv)<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">{<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (argv.length </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">) {<br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">    writefln(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Wrong arguments</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">  }<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> READ_SIZE </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1024</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">  FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fin </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> fopen(argv[</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">], </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">r</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">  FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fout </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> fopen(argv[</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">], </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">w</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> buffer[READ_SIZE];<br /></span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[]] emails;<br /></span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">  PerformanceCounter counter </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> PerformanceCounter();<br /></span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);">  counter.start();<br /></span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">feof(fin)){<br /></span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">    fgets(cast(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)buffer, READ_SIZE, fin);<br /></span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[] email </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> toString(cast(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)buffer);<br /></span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">(email </span><span style="color: rgb(0, 0, 255);">in</span><span style="color: rgb(0, 0, 0);"> emails)){<br /></span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">      emails[toString(buffer)] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);">      fputs(cast(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)email, fout);<br /></span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 0, 0);">    }<br /></span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);">  }<br /></span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 0);">  fclose(fout);<br /></span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 0, 0);">  fclose(fin);<br /></span><span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 0, 0);">  counter.stop();<br /></span><span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">34</span> <span style="color: rgb(0, 0, 0);">  writefln(counter.milliseconds());<br /></span><span style="color: rgb(0, 128, 128);">35</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">36</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 0, 0);"></span></div><br />没加fopen失败处理。<br /><br />测试结果在我的机器上耗时只有python版本的1/3，我看到其它网友的C＋＋实现最好成绩也不过1/2，由于是D是C语言所写，测试使用的又是C库，自然可以认为C语言还是比较高效的。<br /><br />上面的D语言代码里调用了toString，把char*转为char[]，它的源代码如下：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[] toString(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">s)<br />{<br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> s </span><span style="color: rgb(0, 0, 0);">?</span><span style="color: rgb(0, 0, 0);"> s[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> .. strlen(s)] : cast(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">[])</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />}</span></div><br />如果s[0 .. strlen(s)]产生了复制的话，应该是会影响性能的。char[]对象是受GC管理的，应该会复制一份。这种情况下还能有如此高的效率，的确很不错。<br /><br />不过python的性能让我感觉很吃惊，以前只测试过字符串连接，感觉比较高效。<br /><br />写了一个完成一样功能的ruby程序，耗时接近python版本的2倍，当然由于对它不是很熟，可能写得不够高效。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">emails </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Hash.</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">start </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Time.now<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">fout </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> open(</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">email-2-new1.txt</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">w</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">)<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">open(</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">email-2.txt</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">).each </span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">line</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">emails.has_key</span><span style="color: rgb(0, 0, 0);">?</span><span style="color: rgb(0, 0, 0);"> line<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">    emails[line] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">    fout </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> line<br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">  end<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">end<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">puts Time.now </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> start<br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);"></span></div><br />正如某网友所说，这个程序的瓶颈在于IO，拿来作性能上的比较或许是不合适的。从语言效率上来讲，自然是C++和D相当，可能会比D高，python应该会低很多。但在很多情况下，衡量效率不光是语言本身，还有库，没有库的语言是没什么吸引力的。python是一种很“慢”的语言，相对C/C＋＋来说，不过它是一门实用性的语言，所以它为一些特定用法做了优化，取得了不错的成绩。C＋＋是一门通用语言，或许太注重语言的性能了，忽略了库，导致库把性能给拉下来了。这种情况下，有人评测java和C＋＋的性能，结果是java要高，自然是不那么让人惊奇的了。可是如果标准库都这么慢，那还能指望什么呢？<br /><br />当然也并没有证明STL就特别慢，也可能是使用不正确。<br /><br /><br />只是刚好看到这个比较，忍不住参与一下，切勿当真。<br /><img src ="http://www.cppblog.com/cpunion/aggbug/4840.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-31 11:06 <a href="http://www.cppblog.com/cpunion/archive/2006/03/31/4840.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] digitalmars.D上的一个建议。</title><link>http://www.cppblog.com/cpunion/archive/2006/03/28/4675.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 28 Mar 2006 02:31:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/28/4675.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4675.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/28/4675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4675.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4675.html</trackback:ping><description><![CDATA[标题：<font face="Arial" size="-1"><b>Proposal: Operator overloading without temporaries</b></font><br />作者：<font face="Arial" size="-1"><a href="mailto:dac@nospam.com.au">Don Clugston &lt;dac@nospam.com.au&gt;</a><br /><br /></font>正文：<br />Background: Operator overloading, in the form it exists in C++ and <br />currently in D, inherently results in sub-optimal code, because it <br />always results in unnecessary temporary objects being created.<br /><br />For example,<br />X = A - ((B*C) + D)* E;<br /><br />becomes:<br />T1 = B * C;<br />T2 = T1 + D;<br />T3 = T2 * E;<br />T4 = A - T3;<br />X = T4;<br />Four objects were created, whereas only one was strictly required.<br />In C++, there are libraries like Blitz++ which use complicated <br />expression templates in order to avoid these creating these temporaries, <br />and provide performance comparable with FORTRAN. I think D can do much <br />better...<br />Note that temporaries are avoided when using the opXXXAssign() operators <br />like +=.<br /><br />===========<br />   Proposal<br />===========<br />(1) Allow the compiler to assume that b = b + c  can be replaced with b <br />+= c. (In C++, operator + and operator += are just symbols, the compiler <br />doesn't know that there is any relationship between them).<br />In the example above, this would allow the compiler to generate:<br />T1 = B * C;<br />T1 += D;<br />T1 *= E;<br /><br />and we have eliminated two of the three temporaries.<br />(2). Fill in the gaps in the operator overloading table by introducing<br />opAddAssign_r, opSubAssign_r, etc.<br /><br />Just as A.opSubAssign(B)<br />is the operation  A -= B  or equivalently  A = A - B, similarly<br /><br />A.opSubAssign_r(B)<br />would mean<br />A = B - A.<br />and would only occur when temporaries are generated in expressions. Like <br />-=, it's an operation which can frequently be performed very <br />efficiently, but at present the language has no way of expressing it.<br /><br />Our original example then becomes:<br /><br />T1 = B.opMul(C);<br />T1.opAddAssign(D);<br />T1.opMulAssign(E);<br />T1.opSubAssign_r(A);<br />X = T1;<br />... and all the useless temporaries are gone!<br /><br />More formally, when the expression tree for an expression is generated:<br />With a binary operator XXX, operating on left &amp; right nodes:<br /><br />if (the left node is *not* an original leaf node) {<br />    // the left node is a temporary, does not need to be preserved.<br />    // we don't care if the right node is a temporary or not<br />    look for opXXXAssign().<br />} else if (the the right node is not an original leaf node) {<br />    // the right node is a temporary<br />    look for opXXXAssign_r()<br />} else {<br />   // both left and right nodes are leaf nodes, we have to<br />   // create a temporary<br />    look for opXXX(), just as it does now.<br />}<br /><br />These rules also cope with the situation where temporaries are required:<br />eg<br />X = (A*B) + (C*D);<br />becomes<br />T1 = A*B;<br />T2 = C*D;<br />T1 += T2;<br />X = T1;<br /><br />If this were implemented, it would permanently eradicate (for D) the <br />most significant advantage which Fortran has managed to retain over <br />object-oriented languages. And I really don't think it would be <br />difficult to implement, or have negative side-effects.<br /><br />There are a couple of decisions to be made:<br />(I) should the compiler use opAdd() and generate a temporary, if <br />opAddAssign_r() doesn't exist, to preserve existing behaviour? I think <br />the answer to this is YES.<br />(II) should the compiler use opAdd() and generate a temporary, if <br />oppAddAssign() doesn't exist, to preserve existing behaviour? Again, I'm <br />inclined to answer YES.<br />(III) If the code includes +=, and there is an opAdd() but no <br />opAddAssign(), should the compiler accept this, and just generate an <br />opAdd() followed by an assignment?? This would mean that opAdd() would <br />generate the += operation as well as +, while opAddAssign() would be a <br />performance enhancement. (It would still be possible to have <br />opAddAssign() without opAdd(), to have += but not +, but it would not be <br />possible to have + without +=). This would mean that += would be <br />*purely* syntactic sugar.<br /><br />Decision III would be a little more difficult to implement and is of <br />less obvious merit, I only mention it as a possibility.<br /><br />Comments? <br /><img src ="http://www.cppblog.com/cpunion/aggbug/4675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-28 10:31 <a href="http://www.cppblog.com/cpunion/archive/2006/03/28/4675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>D语言模板最近的一些改进</title><link>http://www.cppblog.com/cpunion/archive/2006/03/15/4204.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 15 Mar 2006 09:03:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/15/4204.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4204.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/15/4204.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4204.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4204.html</trackback:ping><description><![CDATA[不知道什么时候加入了“函数模板参数类型推导”和“类模板（改进型）”，文档中也是悄悄出现了。<br>
<br>
函数模板参数类型推导：<br>
<pre class="d_code"><span style="color: blue;">template</span> <b>Square</b>(T)<br>{<br>    T <b>Square</b>(T t)<br>    {<br>	<span style="color: blue;">return</span> t * t;<br>    }<br>}</pre>
以前调用时必须显式实例化：<br>
<pre class="d_code">writefln(<span style="color: red;">"The square of %s is %s"</span>, 3, Square!(<span style="color: blue;">int</span>)(3));<br><br>现在可以使用自动推导了：<br><br>writefln(<span style="color: red;">"The square of %s is %s"</span>, 3, Square(3));  <span style="color: green;">// T is deduced to be int<br><br><br></span>类模板以前必须这样写：<br><span style="color: blue;">template</span> <b>Bar</b>(T)<br>{<br>    <span style="color: blue;">class</span> <b>Bar</b><br>    {<br>	T member;<br>    }<br>}<br><br>现在可以写为：<br><span style="color: blue;">class</span> <b>Bar</b>(T)<br>{<br>    T member;<br>}<br><br>含义相同。<br><span style="color: green;"></span></pre><img src ="http://www.cppblog.com/cpunion/aggbug/4204.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-15 17:03 <a href="http://www.cppblog.com/cpunion/archive/2006/03/15/4204.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从C＋＋到D</title><link>http://www.cppblog.com/cpunion/archive/2006/03/14/4129.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 14 Mar 2006 04:10:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/14/4129.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4129.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/14/4129.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4129.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4129.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 从http://www.digitalmars.com/d/cpptod.html摘录1、构造函数：c++:Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->1&nbsp;class&nbsp;Foo2&nbsp;{3&nbsp;&nbs...&nbsp;&nbsp;<a href='http://www.cppblog.com/cpunion/archive/2006/03/14/4129.html'>阅读全文</a><img src ="http://www.cppblog.com/cpunion/aggbug/4129.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-14 12:10 <a href="http://www.cppblog.com/cpunion/archive/2006/03/14/4129.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DMD 0.149发布</title><link>http://www.cppblog.com/cpunion/archive/2006/03/08/3888.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 08 Mar 2006 03:36:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/08/3888.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/3888.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/08/3888.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/3888.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/3888.html</trackback:ping><description><![CDATA[最近3个版本增加/移除了一些新特性。<BR><BR>0.147中加入了match表达式，不过感觉用处太小了点，果然0.148中又去掉了。<BR>0.148中去掉了bit类型，增加了BitArray类和bool基本类型。on_scope语句算是个比较重要的更新，可用于在代码块结束、异常、成功执行时，完成特定功能。<BR>0.149中on_scope语句改成了scope(...)。<img src ="http://www.cppblog.com/cpunion/aggbug/3888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-08 11:36 <a href="http://www.cppblog.com/cpunion/archive/2006/03/08/3888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DMD 0.141发布</title><link>http://www.cppblog.com/cpunion/archive/2005/12/06/1558.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 06 Dec 2005 02:41:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/06/1558.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1558.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/06/1558.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1558.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1558.html</trackback:ping><description><![CDATA[<H3><A name=new0141>What's New for <A title="D 0.141" href="http://ftp.digitalmars.com/dmd.141.zip">D 0.141</A> </H3>
<P><SMALL><I>Dec 1, 2005</I></SMALL> </P>
<P>
<H4>New/Changed Features</H4>
<UL>
<LI>The predefined version identifier <B>D_InlineAsm</B> has been changed to <B>D_InlineAsm_X86</B>. The former made no sense, and although it is still defined, it is deprecated. 
<LI>Added <A href="http://digitalmars.com/d/code_coverage.html">D code coverage analyzer</A>. 
<LI>Added <B>.mangleof</B> property for types, which gives the 'mangled' type name as a string. </LI></UL>
<H4>Bugs Fixed</H4>
<UL>
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5643">D.bugs/5643</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5668">D.bugs/5668</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5687">D.bugs/5687</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5690">D.bugs/5690</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5673">D.bugs/5673</A> (it now issues an <B>OutOfMemoryException</B>) 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5729">D.bugs/5729</A> 
<LI>Fixed dstress.run.c.creal_26_A regression. 
<LI>Fixed dstress.run.const_18 regression. </LI></UL>
<P><BR><BR>其中“D代码覆盖分析器”应该是很多人感兴趣的东西了，下面是一个例子(摘自<A href="http://digitalmars.com/d/code_coverage.html">http://digitalmars.com/d/code_coverage.html</A>)：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">&nbsp;Eratosthenes&nbsp;Sieve&nbsp;prime&nbsp;number&nbsp;calculation.&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;<BR>bit&nbsp;flags[</SPAN><SPAN style="COLOR: #000000">8191</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i,&nbsp;prime,&nbsp;k,&nbsp;count,&nbsp;iter;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">10&nbsp;iterations\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(iter&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">10</SPAN><SPAN style="COLOR: #000000">;&nbsp;iter</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;count&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;flags[]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;flags.length;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(flags[i])<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;prime&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;prime;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000">&nbsp;(k&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;flags.length)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flags[k]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;prime;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;count&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">\n%d&nbsp;primes\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;count);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR></SPAN></DIV><BR>编译、运行：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">dmd&nbsp;sieve&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">cov<BR>sieve</SPAN></DIV>结果如下：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |/* Eratosthenes Sieve prime number calculation. */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |bit flags[8191];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |int main()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5|{&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp; i, prime, k, count, iter;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1|&nbsp;&nbsp;&nbsp; printf("10 iterations\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp; 22|&nbsp;&nbsp;&nbsp; for (iter = 1; iter &lt;= 10; iter++)<BR>&nbsp;&nbsp;&nbsp;&nbsp; 10|&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; count = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp; 10|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flags[] = true;<BR> 163840|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; flags.length; i++)<BR>&nbsp; 81910|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; if (flags[i])<BR>&nbsp; 18990|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp; prime = i + i + 3;<BR>&nbsp; 18990|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = i + prime;<BR> 168980|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (k &lt; flags.length)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR> 149990|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flags[k] = false;<BR> 149990|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k += prime;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp; 18990|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count += 1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1|&nbsp;&nbsp;&nbsp; printf ("\n%d primes\n", count);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1|&nbsp;&nbsp;&nbsp; return 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |}<BR>sieve.d is 100% covered<BR></DIV><BR>另一个惊喜是mangleof属性，可以得到一个类型被编译器mangle后的名字。不知道mangle对应的中文翻译是什么？大概是“名字转换”吧。一点测试代码：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">import&nbsp;std.stdio;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test();<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test1(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test2(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n);<BR><BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;function&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[])&nbsp;f;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;function&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)&nbsp;f1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;function&nbsp;()&nbsp;f2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(f.mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(f1.mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(f2.mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">.mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;a;<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(a.mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;((</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">test).mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;((</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">test1).mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;((</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">test2).mangleof);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">.mangleof);<BR>}</SPAN></DIV>编译执行结果如下：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">PFiAaZv<BR>PFiZv<BR>PFZv<BR>i<BR>f<BR>PFZv<BR>PFiZv<BR>PFiZv<BR>v</SPAN></DIV><img src ="http://www.cppblog.com/cpunion/aggbug/1558.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-06 10:41 <a href="http://www.cppblog.com/cpunion/archive/2005/12/06/1558.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DMD 0.140发布</title><link>http://www.cppblog.com/cpunion/archive/2005/11/25/1304.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 25 Nov 2005 05:38:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/25/1304.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1304.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/25/1304.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1304.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1304.html</trackback:ping><description><![CDATA[<EM><FONT size=2>Nov 23, 2005</FONT></EM> 
<P>
<H4>New/Changed Features</H4>
<UL>
<LI>Added <B>std.string.soundex</B>. 
<LI>Added <B>std.string.entab</B>. 
<LI>Added <B>std.string.wrap</B>. 
<LI>Added <B>std.string.abbrev</B>. 
<LI>Added <A href="http://www.digitalmars.com/d/phobos/std_windows_charset.html">std.windows.charset</A> (thanks to Stewart Gordon, <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/28246">D/28246</A>). 
<LI>Added <A href="http://www.digitalmars.com/d/phobos/std_demangle.html">std.demangle</A> to demangle D names. 
<LI>Improved promotion of names inside templates. 
<LI>Now allows floating point and string literals as template value arguments. 
<LI>To support the previous, the name mangling of template instances has changed. This will necessitate recompilation of any code that uses templates. 
<LI>std.utf.UtfError is now deprecated. Use std.utf.UtfException instead. </LI></UL>
<H4>Bugs Fixed</H4>
<UL>
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5299">D.bugs/5299</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5353">D.bugs/5353</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5360">D.bugs/5360</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5391">D.bugs/5391</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5429">D.bugs/5429</A> 
<LI>Fixed <A href="http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/5464">D.bugs/5464</A> 
<LI>Fixed <B>std.string.expandtabs</B> so it handles UTF. </LI></UL>
<P><BR>比较感兴趣的是浮点数和字符串常量作为模板值参数，简单测试了一下：<BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">import&nbsp;std.stdio;<BR><BR>template&nbsp;TFloat&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;F)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;F;<BR>}<BR><BR>template&nbsp;TString&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[]&nbsp;S)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[]&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;S;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;TFloat</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">3.14f</SPAN><SPAN style="COLOR: #000000">)&nbsp;PI;<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln(PI.value);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln(TString</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">).value);<BR>}</SPAN></DIV><BR>编译通过，运行结果如下：<BR><BR>3.14<BR>hello<img src ="http://www.cppblog.com/cpunion/aggbug/1304.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-25 13:38 <a href="http://www.cppblog.com/cpunion/archive/2005/11/25/1304.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DMDScript脚本工具，DDL项目</title><link>http://www.cppblog.com/cpunion/archive/2005/11/20/1200.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 19 Nov 2005 16:20:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/20/1200.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1200.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/20/1200.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1200.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1200.html</trackback:ping><description><![CDATA[DMDScript是Digital Mars提供的一个符合ECMA 262规范的脚本语言，采用D语言编写，开放源代码，可以从<A href="http://www.digitalmars.com/dscript">http://www.digitalmars.com/dscript</A>看到详细信息，另外有一个C++的实现版本。<BR><BR>另外2个符合ECMA 262规范的脚本语言分别是Netscape的javascript和Microsoft的JScript，目前DMDScript和其它2个不完全兼容，不过效率要高一些。DMDScript提供了一个简单的测试，生成8190以内的质数，迭代10次，在我的机器上，javascript执行耗时566毫秒，DMDScript执行耗时188毫秒，整整快了3倍。<BR><BR>如果你想实现一个符合ECMA 262标准的脚本语言，建议看这份代码的实现吧，比较简洁，只有400多K。微软那份估计是很难看到了，Netscape那份用C写的，代码大小就有近3M，宏也比较多，看起来要吃力一些。<BR><BR><BR><BR>DDL是dsource.org上的一个有趣的项目，它可以从.obj或.lib文件中加载代码并执行，目前支持COFF、OMF、ELF格式。<img src ="http://www.cppblog.com/cpunion/aggbug/1200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-20 00:20 <a href="http://www.cppblog.com/cpunion/archive/2005/11/20/1200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>D语言的模板</title><link>http://www.cppblog.com/cpunion/archive/2005/11/11/1083.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 11 Nov 2005 09:13:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/11/1083.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1083.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/11/1083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1083.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1083.html</trackback:ping><description><![CDATA[D语言的模板使用非常方便灵活，受够了C＋＋模板编写之苦的同学们可以感受一下D语言的模板，下面先展示一个D语言编写的多分派委托类，在我的旧BLOG上曾经写过一个C＋＋版本的，整个过程感觉非常痛苦。。。<BR><BR>闲话少说，请看代码：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">import&nbsp;std.stdio;<BR><BR><BR>template&nbsp;DelegateHandlers(HandlerType,&nbsp;FunctionType)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;HandlerType[]&nbsp;handlers;<BR>&nbsp;&nbsp;&nbsp;&nbsp;FunctionType[]&nbsp;functions;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;opAddAssign(HandlerType&nbsp;h)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handlers.length&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;handlers.length&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handlers[length</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;h;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;opAddAssign(FunctionType&nbsp;f)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;functions.length&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;functions.length&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;functions[length</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;f;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>template&nbsp;Delegate(Ret)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Delegate<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Ret&nbsp;</SPAN><SPAN style="COLOR: #0000ff">delegate</SPAN><SPAN style="COLOR: #000000">&nbsp;()&nbsp;HandlerType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Ret&nbsp;function&nbsp;()&nbsp;FunctionType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mixin&nbsp;DelegateHandlers</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(HandlerType,&nbsp;FunctionType);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">is</SPAN><SPAN style="COLOR: #000000">(Ret:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;opCall&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(HandlerType&nbsp;handler;&nbsp;handlers)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(FunctionType&nbsp;_function;&nbsp;functions)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_function&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ret&nbsp;opCall&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ret&nbsp;ret;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(HandlerType&nbsp;handler;&nbsp;handlers)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;handler&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(FunctionType&nbsp;_function;&nbsp;functions)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;_function&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;ret;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>template&nbsp;Delegate(Ret,&nbsp;Arg1)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Delegate<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Ret&nbsp;</SPAN><SPAN style="COLOR: #0000ff">delegate</SPAN><SPAN style="COLOR: #000000">&nbsp;(Arg1)&nbsp;HandlerType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Ret&nbsp;function&nbsp;(Arg1)&nbsp;FunctionType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mixin&nbsp;DelegateHandlers</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(HandlerType,&nbsp;FunctionType);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">is</SPAN><SPAN style="COLOR: #000000">(Ret:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;opCall&nbsp;(Arg1&nbsp;a1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(HandlerType&nbsp;handler;&nbsp;handlers)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler&nbsp;(a1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(FunctionType&nbsp;_function;&nbsp;functions)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_function&nbsp;(a1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ret&nbsp;opCall&nbsp;(Arg1&nbsp;a1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ret&nbsp;ret;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(HandlerType&nbsp;handler;&nbsp;handlers)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;handler&nbsp;(a1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(FunctionType&nbsp;_function;&nbsp;functions)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;_function&nbsp;(a1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;ret;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Test.test</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;test1&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Test.test1</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test2(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Test.test2</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;test3(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Test.test3</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">7</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test_func&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>}<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;test_func1&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func1</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test_func2(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func2</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>}<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;test_func3(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func3</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">9</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Test&nbsp;t&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Delegate</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">)&nbsp;DDD;<BR>&nbsp;&nbsp;&nbsp;&nbsp;DDD&nbsp;d&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DDD;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">t.test;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">test_func;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;d&nbsp;();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Delegate</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)&nbsp;DDD1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;DDD1&nbsp;d1&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DDD1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d1&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">t.test1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d1&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">test_func1;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;d1&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(a&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Delegate</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)&nbsp;DDD2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;DDD2&nbsp;d2&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DDD2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d2&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">t.test2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d2&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">test_func2;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;d2&nbsp;(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;alias&nbsp;Delegate</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">)&nbsp;DDD3;<BR>&nbsp;&nbsp;&nbsp;&nbsp;DDD3&nbsp;d3&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DDD3;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d3&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">t.test3;<BR>&nbsp;&nbsp;&nbsp;&nbsp;d3&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">test_func3;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;d3&nbsp;(</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(b&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">9</SPAN><SPAN style="COLOR: #000000">);<BR>}<BR></SPAN></DIV><BR>非常干净，非常简洁，不是吗？这个只花了我10分钟时间来写。。。<BR><BR>D语言的委托非常高效，有兴趣的可以测试一下通过委托和直接调用之间的性能差别。上面这个自己实现的多分派委托类，效率也非常高，我的测试结果是对于性能的影响几乎可以忽略。想起那个历尽千辛万苦实现的C＋＋多分派委托类，实现复杂、调试费时、运行效率还很低，每每一想到这心里那个难受啊。。。。<BR><BR>再来看一下D语言强大的静态检查机制：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;XXX&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;v;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;assert&nbsp;(v&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n;<BR>&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;XXX</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">).n;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;OK</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;XXX</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">).n;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;编译错误</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">}</SPAN></DIV><BR>同样很漂亮。<BR><BR>如果你觉得提示信息不够友好，可以修改为：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;XXX&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;v;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(v&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pragma&nbsp;(msg,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">template&nbsp;value&nbsp;must&nbsp;&gt;&nbsp;3</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;assert&nbsp;(v&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);<BR>}</SPAN></DIV><BR>这是编译时的错误提示：<BR><BR>Compiling test.d ...<BR>template value must &gt; 3<BR>D:\workspace\dace\test.d(94): static assert&nbsp; (3 &gt; 3) is false<BR>D:\workspace\dace\test.d(173): template instance test.XXX!(3) error instantiating<BR><BR>我想以后有可能会扩充pragma，支持错误输出，这样就不用写重复的语句了，可以简化成这样：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;XXX&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;v;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(v&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pragma&nbsp;(error,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">template&nbsp;value&nbsp;must&nbsp;&gt;&nbsp;3</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>}</SPAN></DIV><BR>这样看起来更好。不过目前有很多重要特性要实现，这种玩意可能要很久以后才会加入了。<img src ="http://www.cppblog.com/cpunion/aggbug/1083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-11 17:13 <a href="http://www.cppblog.com/cpunion/archive/2005/11/11/1083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>D语言调用ActiveX（在窗口中嵌入ActiveX）</title><link>http://www.cppblog.com/cpunion/archive/2005/11/11/1061.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 11 Nov 2005 04:16:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/11/1061.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1061.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/11/1061.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1061.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1061.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这是一个从C移植到D的代码，原文请见“Embed an HTML control in your own window using plain C”，它用C结构模拟了虚表，并且实现了多个接口以完成对Web Browser控件的调用。在看完他的代码之后，我对于COM/OLE的了解加深了一些，以前使用VC做过COM方面的应用，也看过不少COM方面的书，不过没有涉及到界面，所以一直不知道如何把Activ...&nbsp;&nbsp;<a href='http://www.cppblog.com/cpunion/archive/2005/11/11/1061.html'>阅读全文</a><img src ="http://www.cppblog.com/cpunion/aggbug/1061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-11 12:16 <a href="http://www.cppblog.com/cpunion/archive/2005/11/11/1061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>D语言中的in/inout/out参数</title><link>http://www.cppblog.com/cpunion/archive/2005/11/10/1044.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 10 Nov 2005 06:51:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/10/1044.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1044.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/10/1044.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1044.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1044.html</trackback:ping><description><![CDATA[<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;import&nbsp;std.stdio,&nbsp;std.process;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a,&nbsp;inout&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;b,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;c)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln(a);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln(b);<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln(c);<BR>&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">7</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;c&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;test(a,&nbsp;b,&nbsp;c);<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(a&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(b&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">5</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(c&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">7</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;std.process.system(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">pause</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>}</SPAN></DIV><BR>在上面的例子里，程序在test函数中的输出语句将输出：<BR>0<BR>1<BR>0<BR>也就是说，out参数取值是无意义的，它只用于赋值。<BR><BR>这里有一个很大的问题，调用test(a,b,c)时，调用者对于c的值被改变可能毫无知觉，甚至成为隐藏很深的BUG。对此，许多人建议加强检查，比如在调用时，必须指明inout/out：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">test(a,&nbsp;inout&nbsp;b,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&nbsp;c);</SPAN></DIV><BR>似乎能够起到一些警示作用，不过这样一来，语法上倒不怎么简练了。<img src ="http://www.cppblog.com/cpunion/aggbug/1044.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-10 14:51 <a href="http://www.cppblog.com/cpunion/archive/2005/11/10/1044.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DMD最近的一些更新</title><link>http://www.cppblog.com/cpunion/archive/2005/11/10/1039.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 10 Nov 2005 04:12:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/10/1039.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1039.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/10/1039.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1039.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1039.html</trackback:ping><description><![CDATA[v0.138 实现了字符串直接切片调用：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[]&nbsp;a&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">abcde</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">..</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln(a);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">abcde</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">[</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">];<BR>&nbsp;&nbsp;&nbsp;&nbsp;writefln(b);</SPAN></DIV><BR>另外修复了一些编译器和文档生成的BUG。<BR><BR>v0.137的重要更新有：<BR>隐式类型引用：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">auto&nbsp;c&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">abcde</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;c变量自动获得类型char[]</SPAN></DIV>extern(linkage)在内嵌函数中使用<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test()<BR>{<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">(C)&nbsp;test1();<BR>}</SPAN></DIV><BR><BR>其它更新则主要集中于编译器工作、文档工具、库等，暂时还没有特别令人兴奋的特性加入进来，比如：stack tracing, relation api等。<img src ="http://www.cppblog.com/cpunion/aggbug/1039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-10 12:12 <a href="http://www.cppblog.com/cpunion/archive/2005/11/10/1039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>D语言令人喜爱的几个地方</title><link>http://www.cppblog.com/cpunion/archive/2005/11/02/902.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 02 Nov 2005 08:35:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/02/902.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/902.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/02/902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/902.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/902.html</trackback:ping><description><![CDATA[1、去掉了丑陋的宏。<BR>C/C++中的宏是很令人厌烦的，D不允许再使用它。<BR><BR>2、好用的字符串常量表达式。<BR>除了类C的使用双引号的字符串常量表达式以外，还可以使用`字符。可以使用x"68 65 6C6C 6F"来表示"hello"，r"ab\na"则忽略字符串常量中转义字符的转义作用，还可以在字符串常量后加上c, w或d来指示字符串常量是char[]类型、wchar[]类型还是dchar[]类型。可以使用~运算符连接2个字符串。<BR><BR>3、数字。<BR>数字可以直接使用，还可以这样来定义：int a = 3_029_301_000; 数字直接量(包括整数、浮点数、复数)表达式中，“_”字符是被忽略的。另外还直接提供了复数类型。<BR><BR>4、提供定长数组、变长数组、关联数组。<BR>int[3] a定义一个定长数组；int [] a定义一个变长数组；int[int]定义一个关联数组，键类型是int，值类型是int；int[char[]] a定义一个关联数组，键类型是char[]，值类型是int，使用非常方便。<BR>可以使用foreach来遍历数组：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;index,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;value;&nbsp;a)<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;printf&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%d:&nbsp;%d\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;index,&nbsp;value);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">foreach</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[]&nbsp;key,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;value;&nbsp;a)<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;printf&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%.*s:&nbsp;%d\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;index,&nbsp;value);</SPAN></DIV><BR>可以使用in操作符来判断某个值是否是关联数组的一个键：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">[]]&nbsp;a;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&nbsp;a)<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV><BR>数组可以切片(slice)：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;a;&nbsp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;b&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;a[</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">..</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">];&nbsp;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">[]&nbsp;c&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;a[</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">..length];</SPAN></DIV><BR>等等。。。。<BR><BR>5、其它还支持委托、函数指针、模板、异常、RAII、契约式编程、单元测试、with语句、auto/typeof、垃圾回收、操作符重载、内联汇编、条件编译、嵌入到HTML等，它还标准化了ABI(这是C/C++最让人头痛的地方之一)。这些特性大部分都比较熟悉和实用，下面简单介绍一下条件编译和嵌入到HTML。<BR><BR>6、条件编译。<BR>在D中，可以使用version(VersionID)来进行条件编译：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">version&nbsp;(Win32)<BR>{<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">..</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">}</SPAN></DIV><BR>还可以使用debug条件：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">debug<BR>{<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">}</SPAN></DIV><BR>或者：<BR>debug printf ("hello");<BR>静态条件编译：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(n&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV><BR>类型检查：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;n&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">is</SPAN><SPAN style="COLOR: #000000">(n[]))<BR>&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">like&nbsp;array</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">is</SPAN><SPAN style="COLOR: #000000">(n:</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">))<BR>&nbsp;&nbsp;writefln&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">is&nbsp;an&nbsp;integer</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV><BR><BR>7、嵌入HTML。<BR>在一个HTML文件中，&lt;code&gt;和&lt;/code&gt;之间的部分可以当作D代码来编译。比如下面这段代码：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">h1</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">This&nbsp;is&nbsp;a&nbsp;test</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">h1</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">code</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>import&nbsp;std.c.stdio;<BR><BR>int&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">font&nbsp;</SPAN><SPAN style="COLOR: #ff0000">size</SPAN><SPAN style="COLOR: #0000ff">=+1</SPAN><SPAN style="COLOR: #0000ff">&gt;&lt;</SPAN><SPAN style="COLOR: #800000">b</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">main</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">b</SPAN><SPAN style="COLOR: #0000ff">&gt;&lt;/</SPAN><SPAN style="COLOR: #800000">font</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">()<BR>{<BR></SPAN><SPAN style="COLOR: #ff0000">&amp;nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">span&nbsp;</SPAN><SPAN style="COLOR: #ff0000">style</SPAN><SPAN style="COLOR: #0000ff">="color:red"</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">printf</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">span</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">u</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #ff0000">&amp;quot;</SPAN><SPAN style="COLOR: #000000">hello&nbsp;world\n</SPAN><SPAN style="COLOR: #ff0000">&amp;quot;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">u</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #ff0000">&amp;nbsp;</SPAN><SPAN style="COLOR: #000000">return&nbsp;0;<BR>}<BR></SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">code</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">hr&nbsp;</SPAN><SPAN style="COLOR: #0000ff">/&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">&lt;</SPAN><SPAN style="COLOR: #800000">h1</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;End&nbsp;</SPAN><SPAN style="COLOR: #0000ff">&lt;/</SPAN><SPAN style="COLOR: #800000">h1</SPAN><SPAN style="COLOR: #0000ff">&gt;</SPAN></DIV><BR>把它存储为HTML文件，可以直接使用dmd编译器编译。<img src ="http://www.cppblog.com/cpunion/aggbug/902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-02 16:35 <a href="http://www.cppblog.com/cpunion/archive/2005/11/02/902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>配置D语言编程环境</title><link>http://www.cppblog.com/cpunion/archive/2005/11/02/892.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 02 Nov 2005 03:17:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/11/02/892.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/892.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/11/02/892.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/892.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/892.html</trackback:ping><description><![CDATA[D语言是由Walter Bright开发的，他也是Symantec C++编译器的作者，仅凭这一点就知道D语言一定不错。<BR><BR>D语言的介绍最好是看<A href="http://blog.csdn.net/uframer">uframer的blog</A>，他翻译了D语言的大部分文档。当然由于D语言目前一直处于测试版，文档和最新的编译器之间可能有很多不一致。<BR><BR>D语言的编译器目前有2个，DMD和GDC，DMD比较容易配置，可以从<A href="http://www.digitalmars.com/d/dcompiler.html">http://www.digitalmars.com/d/dcompiler.html</A>下载最新版。下载的压缩包直接解压到任意一个分区的根目录，并把\dm\bin和\dmd\bin加到PATH环境变量里即可使用。<BR><BR>写一个简单的D语言程序，当然还是经典的HelloWorld程序：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Hello&nbsp;world!\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>}</SPAN></DIV><BR>和C程序基本上一样。把它保存为hello_world.d。<BR><BR>下面直接在这个源文件所在的目录下，执行dmd hello_world.d，即可编译出hello_world.exe，执行它就能在控制台打印出Hello world!。<BR><BR>接下来到<A href="http://www.dsource.org/projects/build/">http://www.dsource.org/projects/build/</A>下载build程序，这是在D社区使用比较广泛的一个程序。由于最新的v2.09版已经发现了一些严重的BUG，所以最好到<A href="http://svn.dsource.org/projects/build/downloads/">http://svn.dsource.org/projects/build/downloads/</A>下载v2.08版。把下载的.exe文件改名为build.exe并放置合适的文件夹下，并设置PATH环境变量。(为简单起见我是直接把它放在\dm\bin文件夹下)<BR><BR>下面测试一下build程序，编写一个hello_world.brf文件，保存在hello_world.d同一路径下，文件内容如下：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">cleanup<BR>hello_world.d</SPAN></DIV>
<P><BR>然后执行build @hello_world即可编译出hello_world.exe。</P>
<P>akIDE是一个D语言的IDE，可以到<A href="http://www.lessequal.com/akide">http://www.lessequal.com/akide</A>下载，它只需要DMD支持。<BR><BR>D语言编译速度非常快(这也是Walter Bright对C++不满的一个重要原因)。dsource.org中的mango项目包含755个D源文件，但在我的机器上编译成.lib文件只需要4秒时间。<BR><BR>D语言性能也很不错，有2篇D语言和C/C++、Java、C#的性能比较文章：<A href="http://mag.vchelp.net/200312/fanyi.htm"><BR>http://mag.vchelp.net/200312/fanyi.htm</A><BR><A href="http://mag.vchelp.net/200312/fanyi_2.htm">http://mag.vchelp.net/200312/fanyi_2.htm</A><BR><BR>相关项目介绍：<BR>mango: 这是一个专注于服务端编程的项目，目前主要由Kris开发、维护，实现了servlet，暂时还没有太复杂的功能，不过很值得期待。<BR>dwt: D语言的swt开发包，界面开发首选。看过eclipse界面的应该有比较深的印象。由于大部分代码是从java代码转换过来的，所以类名、接口等都没有改变。<BR>dui: D语言的别一个界面开发包，基于GTK。<BR>build: 上面介绍过的build工具。<BR>dcoder: 基于vs.net的D语言语法高亮插件。<BR>dsp: 全称是Dynamic Servlet Pages。<BR><BR>以上项目都可以在<A href="http://www.dsource.org/projects/">http://www.dsource.org/projects/</A>找到详细资料。<BR><BR>DMDScript是一个类似于JavaScript的脚本系统，可以在<A href="http://www.digitalmars.com/dscript/">http://www.digitalmars.com/dscript/</A>找到详细资料，这个我还没有使用过。<BR><BR><BR>最后附上2个使用dwt开发的界面<STRONG><FONT style="BACKGROUND-COLOR: #ffffff" color=#ff0000>(注：由于本人不习惯安装杀毒软件，下载请先杀毒)：</FONT></STRONG><BR>1、仿eclipse界面：<BR><A href="/Files/cpunion/dummyeclipse.rar">http://www.cppblog.com/Files/cpunion/dummyeclipse.rar</A><BR>2、dwt控件演示：<BR><A href="/Files/cpunion/controlexample.rar">http://www.cppblog.com/Files/cpunion/controlexample.rar</A><BR><BR>在windows xp主题下效果比较好。这2个程序在我的机器上分别只占6.4M和7.2M内存，启动时间也不足1秒，不要被eclipse的启动时间吓坏了。<BR><BR>
<HR>
<BR>找到了这2张图：<BR><IMG height=607 alt=controlexample.png src="http://www.cppblog.com/images/cppblog_com/cpunion/myimages/controlexample.png" width=794 border=0><IMG height=380 alt=dummyeclipse.png src="http://www.cppblog.com/images/cppblog_com/cpunion/myimages/dummyeclipse.png" width=497 border=0></P><img src ="http://www.cppblog.com/cpunion/aggbug/892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-11-02 11:17 <a href="http://www.cppblog.com/cpunion/archive/2005/11/02/892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>