- 浏览: 492907 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
hypercube:
markin'
配置D语言编程环境 -
qiezi:
qiezi 写道yangyang_08 写道1 ...
我的编程语言学习经历 -
qiezi:
yangyang_08 写道1、现在如果做并发服务器,楼主选用 ...
我的编程语言学习经历 -
yangyang_08:
1、现在如果做并发服务器,楼主选用什么样的语言架构?2、lua ...
我的编程语言学习经历 -
dearplain:
我也是语言爱好者,不过我一直坚持使用c。
我的编程语言学习经历
D语言的模板使用非常方便灵活,受够了C++模板编写之苦的同学们可以感受一下D语言的模板,下面先展示一个D语言编写的多分派委托类,在我的旧BLOG上曾经写过一个C++版本的,整个过程感觉非常痛苦。。。
闲话少说,请看代码:
非常干净,非常简洁,不是吗?这个只花了我10分钟时间来写。。。
D语言的委托非常高效,有兴趣的可以测试一下通过委托和直接调用之间的性能差别。上面这个自己实现的多分派委托类,效率也非常高,我的测试结果是对于性能的影响几乎可以忽略。想起那个历尽千辛万苦实现的C++多分派委托类,实现复杂、调试费时、运行效率还很低,每每一想到这心里那个难受啊。。。。
再来看一下D语言强大的静态检查机制:
同样很漂亮。
如果你觉得提示信息不够友好,可以修改为:
这是编译时的错误提示:
Compiling test.d ...
template value must > 3
D:\workspace\dace\test.d(94): static assert (3 > 3) is false
D:\workspace\dace\test.d(173): template instance test.XXX!(3) error instantiating
我想以后有可能会扩充pragma,支持错误输出,这样就不用写重复的语句了,可以简化成这样:
这样看起来更好。不过目前有很多重要特性要实现,这种玩意可能要很久以后才会加入了。
闲话少说,请看代码:
import std.stdio;
template DelegateHandlers(HandlerType, FunctionType)
{
HandlerType[] handlers;
FunctionType[] functions;
void opAddAssign(HandlerType h)
{
handlers.length = handlers.length + 1;
handlers[length-1] = h;
}
void opAddAssign(FunctionType f)
{
functions.length = functions.length + 1;
functions[length-1] = f;
}
}
template Delegate(Ret)
{
class Delegate
{
alias Ret delegate () HandlerType;
alias Ret function () FunctionType;
mixin DelegateHandlers!(HandlerType, FunctionType);
static if(is(Ret: void))
{
void opCall ()
{
foreach (HandlerType handler; handlers)
handler ();
foreach (FunctionType _function; functions)
_function ();
}
}
else
{
Ret opCall ()
{
Ret ret;
foreach (HandlerType handler; handlers)
ret = handler ();
foreach (FunctionType _function; functions)
ret = _function ();
return ret;
}
}
}
}
template Delegate(Ret, Arg1)
{
class Delegate
{
alias Ret delegate (Arg1) HandlerType;
alias Ret function (Arg1) FunctionType;
mixin DelegateHandlers!(HandlerType, FunctionType);
static if(is(Ret: void))
{
void opCall (Arg1 a1)
{
foreach (HandlerType handler; handlers)
handler (a1);
foreach (FunctionType _function; functions)
_function (a1);
}
}
else
{
Ret opCall (Arg1 a1)
{
Ret ret;
foreach (HandlerType handler; handlers)
ret = handler (a1);
foreach (FunctionType _function; functions)
ret = _function (a1);
return ret;
}
}
}
}
class Test
{
void test ()
{
writefln ("Test.test");
}
int test1 ()
{
writefln ("Test.test1");
return 1;
}
void test2(int v)
{
writefln ("Test.test2");
}
int test3(int v)
{
writefln ("Test.test3");
return 7;
}
}
void test_func ()
{
writefln ("test_func");
}
int test_func1 ()
{
writefln ("test_func1");
return 2;
}
void test_func2(int v)
{
writefln ("test_func2");
}
int test_func3(int v)
{
writefln ("test_func3");
return 9;
}
void main()
{
Test t = new Test;
alias Delegate!(void) DDD;
DDD d = new DDD;
d += &t.test;
d += &test_func;
d ();
alias Delegate!(int) DDD1;
DDD1 d1 = new DDD1;
d1 += &t.test1;
d1 += &test_func1;
int a = d1 ();
assert (a == 2);
alias Delegate!(void, int) DDD2;
DDD2 d2 = new DDD2;
d2 += &t.test2;
d2 += &test_func2;
d2 (1);
alias Delegate!(int, int) DDD3;
DDD3 d3 = new DDD3;
d3 += &t.test3;
d3 += &test_func3;
int b = d3 (2);
assert (b == 9);
}
template DelegateHandlers(HandlerType, FunctionType)
{
HandlerType[] handlers;
FunctionType[] functions;
void opAddAssign(HandlerType h)
{
handlers.length = handlers.length + 1;
handlers[length-1] = h;
}
void opAddAssign(FunctionType f)
{
functions.length = functions.length + 1;
functions[length-1] = f;
}
}
template Delegate(Ret)
{
class Delegate
{
alias Ret delegate () HandlerType;
alias Ret function () FunctionType;
mixin DelegateHandlers!(HandlerType, FunctionType);
static if(is(Ret: void))
{
void opCall ()
{
foreach (HandlerType handler; handlers)
handler ();
foreach (FunctionType _function; functions)
_function ();
}
}
else
{
Ret opCall ()
{
Ret ret;
foreach (HandlerType handler; handlers)
ret = handler ();
foreach (FunctionType _function; functions)
ret = _function ();
return ret;
}
}
}
}
template Delegate(Ret, Arg1)
{
class Delegate
{
alias Ret delegate (Arg1) HandlerType;
alias Ret function (Arg1) FunctionType;
mixin DelegateHandlers!(HandlerType, FunctionType);
static if(is(Ret: void))
{
void opCall (Arg1 a1)
{
foreach (HandlerType handler; handlers)
handler (a1);
foreach (FunctionType _function; functions)
_function (a1);
}
}
else
{
Ret opCall (Arg1 a1)
{
Ret ret;
foreach (HandlerType handler; handlers)
ret = handler (a1);
foreach (FunctionType _function; functions)
ret = _function (a1);
return ret;
}
}
}
}
class Test
{
void test ()
{
writefln ("Test.test");
}
int test1 ()
{
writefln ("Test.test1");
return 1;
}
void test2(int v)
{
writefln ("Test.test2");
}
int test3(int v)
{
writefln ("Test.test3");
return 7;
}
}
void test_func ()
{
writefln ("test_func");
}
int test_func1 ()
{
writefln ("test_func1");
return 2;
}
void test_func2(int v)
{
writefln ("test_func2");
}
int test_func3(int v)
{
writefln ("test_func3");
return 9;
}
void main()
{
Test t = new Test;
alias Delegate!(void) DDD;
DDD d = new DDD;
d += &t.test;
d += &test_func;
d ();
alias Delegate!(int) DDD1;
DDD1 d1 = new DDD1;
d1 += &t.test1;
d1 += &test_func1;
int a = d1 ();
assert (a == 2);
alias Delegate!(void, int) DDD2;
DDD2 d2 = new DDD2;
d2 += &t.test2;
d2 += &test_func2;
d2 (1);
alias Delegate!(int, int) DDD3;
DDD3 d3 = new DDD3;
d3 += &t.test3;
d3 += &test_func3;
int b = d3 (2);
assert (b == 9);
}
非常干净,非常简洁,不是吗?这个只花了我10分钟时间来写。。。
D语言的委托非常高效,有兴趣的可以测试一下通过委托和直接调用之间的性能差别。上面这个自己实现的多分派委托类,效率也非常高,我的测试结果是对于性能的影响几乎可以忽略。想起那个历尽千辛万苦实现的C++多分派委托类,实现复杂、调试费时、运行效率还很低,每每一想到这心里那个难受啊。。。。
再来看一下D语言强大的静态检查机制:
template XXX (int v)
{
int n = v;
static assert (v > 3);
}
void main ()
{
int n;
n = XXX!(4).n; // OK
n = XXX!(3).n; // 编译错误
}
{
int n = v;
static assert (v > 3);
}
void main ()
{
int n;
n = XXX!(4).n; // OK
n = XXX!(3).n; // 编译错误
}
同样很漂亮。
如果你觉得提示信息不够友好,可以修改为:
template XXX (int v)
{
int n = v;
static if (v <= 3)
pragma (msg, "template value must > 3");
static assert (v > 3);
}
{
int n = v;
static if (v <= 3)
pragma (msg, "template value must > 3");
static assert (v > 3);
}
这是编译时的错误提示:
Compiling test.d ...
template value must > 3
D:\workspace\dace\test.d(94): static assert (3 > 3) is false
D:\workspace\dace\test.d(173): template instance test.XXX!(3) error instantiating
我想以后有可能会扩充pragma,支持错误输出,这样就不用写重复的语句了,可以简化成这样:
template XXX (int v)
{
int n = v;
static if (v <= 3)
pragma (error, "template value must > 3");
}
{
int n = v;
static if (v <= 3)
pragma (error, "template value must > 3");
}
这样看起来更好。不过目前有很多重要特性要实现,这种玩意可能要很久以后才会加入了。
发表评论
-
D语言模板和编译期执行
2012-07-29 00:15 0D语言模板继承了C++模板的基本用法,在其上做了相当多扩充,近 ... -
Generator
2008-04-09 13:46 1981几种并发编程模型开销(从大到小): Process > ... -
lambda之路...
2007-11-09 22:57 2843DMD最近的版本号加入了闭包,感觉非常有用,虽然有些背后动作, ... -
像Erlang一样写D程序
2007-09-15 10:23 6705琢磨了好久,一直没时间来做它。在讨论这个问题的时候就已经有这想 ... -
[D语言] qsort的尴尬
2007-05-06 21:31 5051phobos里面在stc.c.stdlib里提供了qsort, ... -
强类型数值计算
2007-04-10 21:45 4681以前曾经讨论过使用typedef来完成强类型的数值计算,最终遇 ... -
简单的单元测试框架
2007-04-10 21:20 3122做了个简单的单元测试框架,只算个毛坯,遇到一些问题。 1、由 ... -
仿STL的vector,写了一组array操作方法。
2007-04-05 23:55 11955文档从MSDN抄过来的,稍稍改了一下。 module ar ... -
编译期执行的效率
2007-03-15 15:58 4187写了一个编译期执行的fibonacci模板: templ ... -
D语言编译期生成和编译期执行技术
2007-02-24 14:35 4099借助D语言新的mixin表达式,可以完成一些代码生成功能,比如 ... -
如何获得一个方法的名字?
2007-01-15 19:24 3463在D语言中,一个方法你可以得到它的指针(函数指针或委托),但不 ... -
D语言的函数编程
2007-01-07 11:17 3824前阵子论坛上有人问我D语言做函数编程怎样,老实说我没怎么想过这 ... -
D语言和python的差异
2007-01-07 10:12 6516这2个语言的比较怪怪的,我最近转换了一些twisted的源文件 ... -
从简单测试看D数组内存分配策略
2007-01-07 09:43 3203D语言动态数组可以在运行期改变大小,这和C++的vector相 ... -
DMD 0.178发布
2006-12-24 15:32 4568What's New for D 0.178 ... -
GDC 0.20发布
2006-12-17 14:35 2766引用 * Updated to DMD 0.177 * Fix ... -
DMD 0.177发布
2006-12-09 18:47 2249没什么亮点,BUG修复得也不多,BUG数量始终保持在250-2 ... -
DMD 0.176发布
2006-12-03 14:22 3033引用 What's New for D 0.176 Dec ... -
D语言的成员函数模板
2006-12-02 20:29 3047DMD 0.166 特性列表中有一条: * ncorp ... -
D语言 在栈上分配对象 以及 无需GC拖管对象
2006-11-28 13:18 2772一、栈上分配对象 C++可以轻易实现在栈上和堆上分配对象,例 ...
相关推荐
D语言(Dlang)是由Digital Mars公司开发的编程语言,起因是为了改进C++。它与C二进制兼容(不完全),可编译为本地码,有GC也可手动管理内存,语法上借鉴多种语言,模板则 在C++的基础上做了相当大的扩充。D 语言...
D语言是由Digital Mars公司开发的编程语言,起因是为了改进C++。它与C二进制兼容(不完全),可编译为本地码,有GC也可手动管理内存,语法上借鉴多种语言,模板则在C++的基础上做了相当大的扩充。D 语言既有 C ...
D语言是由Digital Mars公司开发的编程语言,起因是为了改进C++。它与C二进制兼容(不完全),可编译为本地码,有GC也可手动管理内存,语法上借鉴多种语言,模板则在C++的基础上做了相当大的扩充。D 语言既有 C ...
D语言是由Digital Mars公司开发的编程语言,起因是为了改进C++。它与C二进制兼容(不完全),可编译为本地码,有GC也可手动管理内存,语法上借鉴多种语言,模板则在C++的基础上做了相当大的扩充。D 语言既有 C ...
D、模板管理,后台编辑模板更方便 E、邮件发送,表单留言自动发送邮件到邮箱 F、数据缓存,访问速度更快 G、会员自定义模型、字段 H、结合Smarty开发的万能loop标签,数据调用更简单、更方便 I、产品多图多方位...
"求职信模板.doc" 本资源是一个求职信模板,用于 求职者撰写求职信时的参考。该模板包括对应的格式、用语和...10. 个性化的重要性:在写作求职信时,需要个性化,展示自己的特长和优势,避免使用模板和公式化的语言。
在本文中,我们将从英语论文模板的角度,探讨英语教学中 communicative competence 的培养,特别是通过课外活动和语言教学的结合。我们的讨论将围绕这篇论文的结构和内容展开。 首先,让我们来了解论文的结构。论文...
状态: 变量[a-zA-Z$_][a-zA-Z0-9$_]* 筛选器测验评论空格控制转义行语句评论积木模板继承基本模板子模板超级方块嵌套扩展命名块结束标签块嵌套和范围模板对象HTML转义(工作) 使用手动转义使用自动转义控制结构...
Wordpress是目前使用最为广泛的博客系统,使用PHP语言开发,可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站,功能强大、简单易用。其中使用主题功能更是可以让你快速建立起一个美观的网站,但也有其不足之...
b. 语言编译系统或汇编系统的名称及版本号; c. 数据库管理系统的名称及版本号; d. 其他必要的支持软件。】 4.使用说明 4.1安装和初始化 【给出程序的存储形式、操作命令、反馈信息及其含意、表明安装完成的测试...
lovefc_Template是一个小巧,轻便,高效率的模板引擎,只有区区的十几k的大小,提供了一个模板引擎最为基础的功能,此外,还有一些对于模板语言的可扩展性,你完全可以利用它来打造自己的模板代码,更快方便的书写...
R++是专为懒人设计的山寨编程语言,支持无操作系统裸奔、编译成机器码、android、cocos2dx绑定、中文编程、闭包、Lisp的S表达式、内联汇编、伪代码、模板、宏、多重继承、元编程、反射、自省、指针、引用。...
10.d_tag文章热门标签展示 11.error自定义404页面error 页面 12.captcha自定义验证码,数字验证码,字母验证码 13.web_1.0.1站点管理(多站安装&多语言&站群) 14.multiupload批量上传文章 15.admin_journal...
本文档提供了一份完整的工商管理求职简历模板范文,涵盖了个人基本情况、教育经历、工作经历、获奖状况、语言能力、工作能力及其他专长等多方面的信息。这份简历模板适合刚毕业的大学生或具有工商管理经验的求职者,...
Microsoft Windows® PowerShell 是一种新的命令行外壳和脚本语言,用于进行系统管理和自动化。Windows PowerShell 建立在 .NET Framework 的基础上,可使 IT 专业人员和开发人员控制和自动完成 Windows 和应用程序...
hristopher D.Manning,Hinrich Schutze.Fou ndations of Statistical Natural Language Processing,The MIT Press,1999. 3.中译本:苑春 法等译,统计自然语言处理基础,电子工业出版社,2005.
在EPLAN P8 2.7破解教程.rar压缩包里面,将破解补丁“version.dll”复制到安装目录下,默认目录为C:Program FilesEPLANPlatform2.7.3Bin(我把程序装到了D盘之中),然后重启Eplan即可。 用管理员权限打开PYG_DLL_...
Dédalo发布模板口述历史的基本Dédalo发布模板的教学示例当前存储库的目的是允许访问基于Dédalo发布系统的非常简单的网站示例,并说明DédaloAPI REST的用法以及如何发出请求并管理原始javascript中的记录。...
单页模块、文章模块、产品模块、招聘模块、留言反馈、WAP已发布功能:自定义URL规则、URLRewrite伪静态、区块缓存、页面缓存、编译缓存、远程附件、数据库备份恢复、多语言设置、多语言二级域名访问、自定义模板风格...
语言模板 一个OpenFn适配器,用于构建与____ API一起使用的集成作业。 文献资料 查看位于的文档 要更新文档站点,请运行: ./node_modules/.bin/jsdoc --readme ./README.md ./lib -d docs / ./node_modules/.bin/...