- 浏览: 497724 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
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 2007几种并发编程模型开销(从大到小): Process > ... -
lambda之路...
2007-11-09 22:57 2866DMD最近的版本号加入了闭包,感觉非常有用,虽然有些背后动作, ... -
像Erlang一样写D程序
2007-09-15 10:23 6732琢磨了好久,一直没时间来做它。在讨论这个问题的时候就已经有这想 ... -
[D语言] qsort的尴尬
2007-05-06 21:31 5076phobos里面在stc.c.stdlib里提供了qsort, ... -
强类型数值计算
2007-04-10 21:45 4720以前曾经讨论过使用typedef来完成强类型的数值计算,最终遇 ... -
简单的单元测试框架
2007-04-10 21:20 3147做了个简单的单元测试框架,只算个毛坯,遇到一些问题。 1、由 ... -
仿STL的vector,写了一组array操作方法。
2007-04-05 23:55 12031文档从MSDN抄过来的,稍稍改了一下。 module ar ... -
编译期执行的效率
2007-03-15 15:58 4222写了一个编译期执行的fibonacci模板: templ ... -
D语言编译期生成和编译期执行技术
2007-02-24 14:35 4121借助D语言新的mixin表达式,可以完成一些代码生成功能,比如 ... -
如何获得一个方法的名字?
2007-01-15 19:24 3491在D语言中,一个方法你可以得到它的指针(函数指针或委托),但不 ... -
D语言的函数编程
2007-01-07 11:17 3856前阵子论坛上有人问我D语言做函数编程怎样,老实说我没怎么想过这 ... -
D语言和python的差异
2007-01-07 10:12 6554这2个语言的比较怪怪的,我最近转换了一些twisted的源文件 ... -
从简单测试看D数组内存分配策略
2007-01-07 09:43 3227D语言动态数组可以在运行期改变大小,这和C++的vector相 ... -
DMD 0.178发布
2006-12-24 15:32 4601What's New for D 0.178 ... -
GDC 0.20发布
2006-12-17 14:35 2798引用 * Updated to DMD 0.177 * Fix ... -
DMD 0.177发布
2006-12-09 18:47 2275没什么亮点,BUG修复得也不多,BUG数量始终保持在250-2 ... -
DMD 0.176发布
2006-12-03 14:22 3072引用 What's New for D 0.176 Dec ... -
D语言的成员函数模板
2006-12-02 20:29 3074DMD 0.166 特性列表中有一条: * ncorp ... -
D语言 在栈上分配对象 以及 无需GC拖管对象
2006-11-28 13:18 2810一、栈上分配对象 C++可以轻易实现在栈上和堆上分配对象,例 ...
相关推荐
- **模板元编程**:深入探讨了D语言模板系统的高级特性,包括特例化、名称查询、模板递归等。 #### 七、D语言的内存管理和异常处理 - **内存管理**:详细阐述了D语言中的不同内存管理策略,如写时复制、实时内存...
2. **模板**:D语言的模板系统非常强大,可以用于创建泛型函数和泛型类型。模板能够帮助程序员编写高度通用的代码,减少重复工作,提高代码复用性。 3. **内存管理**:D语言具有自动垃圾回收机制,同时支持手动内存...
3. **模板**:D语言的模板类似于C++的模板,允许创建泛型函数和类,实现代码重用,减少冗余。 4. **内存管理**:D语言提供了垃圾回收机制,自动管理内存,但同时也允许程序员直接控制内存,以满足对性能有高要求的...
3. **模板系统**:D语言的模板系统比C++的更加强大和灵活,允许开发者创建更复杂的泛型代码。 4. **契约式设计**:通过断言和 invariant,D语言支持契约式编程,有助于确保代码的正确性。 5. **高级模板技术**:D...
1. **D语言基础**:D语言由Walter Bright创建,具有C/C++语法的相似性,但提供了更多现代编程语言的特性,如垃圾回收、模板元编程、自动类型推断等。理解D语言的基本语法、数据类型、控制结构以及面向对象特性是开始...
- 泛型函数:D语言的模板功能允许编写泛型函数,实现代码复用。 - 泛型类:同样,也可以创建泛型类,通过类型参数实现不同类型的实例。 6. 并发与多线程 - 并发:D语言支持原生的并发模型,包括线程(thread)、...
6. **元编程**:D语言的模板系统允许在编译时进行元编程,使得开发者可以在代码中编写代码,提高代码的灵活性和效率。 7. **性能**:由于D语言的编译器(如解压包中的DMD,D语言的官方编译器)优化能力强,生成的...
**D语言IDE:Poseidon** D语言是一种现代的系统编程语言,它旨在融合了C#、Java、C++以及PHP和Python等动态语言的优势。D语言的独特之处在于它不依赖虚拟机,而是编译成可执行代码,这使得它在性能上具有显著优势。...
由于可以直接生成机器码,D语言的程序执行速度快,而且它的模板元编程和内联函数等功能,允许在编译期进行计算,进一步提高了代码的运行效率。 此外,D语言还有强大的标准库,涵盖了字符串处理、网络编程、并发处理...
D语言还引入了模板,这是一种泛型编程的机制,类似于C++的模板,但更为强大和灵活。它可以用于创建泛型函数和泛型类,允许编写一次代码并应用于多种数据类型,提高了代码的重用性。同时,D语言的模板具有元编程能力...
D语言是一种现代化的系统编程语言,由沃斯·安德烈亚斯·施密特(Walter Bright)设计,旨在结合C和C++的优点并消除它们的一些缺点。它以其高效、安全和强大的元编程能力而受到程序员的青睐。在"编译时开发D语言"的...
D语言的设计目标之一是提高编程效率,因此它提供了一些高级特性,如垃圾回收、类型推断、模板元编程以及自动并行化。这些特性使得开发者能够在编写高效代码的同时,减少许多常见的编程错误和繁琐的管理工作。 垃圾...
D语言是一种现代、通用、面向对象的编程语言,它的设计目标是高效、灵活性高,并且具有C/C++的性能。D语言由Walter Bright在2001年创建,至今已发展到2.0版本,提供了许多现代编程语言的特性。本参考手册详细介绍了D...
### D语言编程手册知识点梳理 #### 一、D语言概览 - **D语言起源与发展**:D语言是由Walter Bright设计的一种通用编程语言,旨在解决C++中存在的问题,并引入了现代语言的一些特性。该语言的目标是提高开发效率的...
6. **模板**:D语言的模板允许泛型编程,不仅应用于类和函数,还可以用于接口和枚举,实现高度的代码复用。 7. **标准库**:D语言的标准库提供了大量实用的函数和数据结构,涵盖输入/输出、字符串处理、网络编程、...
- 元编程是指在编译时进行计算的能力,D语言的模板支持复杂的元编程技术。 - 通过示例展示了如何利用模板来实现高效且灵活的代码。 3. **类型推断与重载**: - 类型推断减少了显式指定类型的需要。 - 重载允许...