代码改变世界

周末话题-元编程(metaprogramming)

2008-08-09 10:44  横刀天笑  阅读(6814)  评论(11编辑  收藏  举报
在计算机行业永远不缺乏的是什么?

概念和新名词

 

我们已经见了太多太多的名词,现在都有点名词麻痹症了。就在这些名词中间有一个单词忽隐忽现的闪烁着自己的光芒----meta

在牛津大辞典里对meta这样解释:它是个词根,构成名词、形容词和动词。1.connected with a change of position or state 位置或状态的变化的。2.higher,beyond 高于,在上:metaphysics形而上学,metalangugage 元语言

呵呵,还有元语言这个词条:用于讲述或描述语言或某种语言的词或短语。

 

看了上面的解释还是没啥感觉。那看看meta这个词一般用在什么地方呢?

 

在我们的.NET里面我们几乎在所有的技术文档里都会看到metadata(元数据)这个东西,元数据就是编译器生成程序集的时候生成的一些额外的信息,这些信息用来描述程序集,类型、方法等东东的,这样在运行时JIT可以加以利用,GC也可以看看,俺们自己还可以通过反射来瞧瞧。嗯,这东西好像就是描述性的东西。

 

HTML里面有一个<meta />的标签,这玩意儿又有什么作用呢?做web的也许都知道这个标签是为网页提供一些附加信息,对搜索引擎友好,比如你可以通过这个meta里说明这网页是你做的,你用啥工具做的,这个网页里包括一些什么内容。

呵,这东西好像还是描述性的东西。

 

不过我们今天的话题:元编程(metaprogramming),这里的元和编程加起来又是什么概念呢?根据前面对meta这个单词的理解,是不是就是描述性编程,我编的这代码的作用就是描述别的代码的。

 

嘿嘿,我在Wiki上找到了一句说明:Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at compile time that is otherwise done at run time.In many cases, this allows programmers to get more done in the same amount of time as they would take to write all the code manually

元编程就是编写计算机程序来编写或操作其它程序(或它自己)作为它们的数据,或者是在编译时而不是运行时干一部分工作。大多数情况下,在同一时间里程序员使用元编程比手写代码更有效率。

 

看了上面的说明,元编程好像是写个代码,让这个代码自己生成代码。

一下子我就想到了C++里面的模板(C#里为泛型,但却有很多不同,此处的模板不是指设计模式里面的模板方法),假如有这样一个通用的算法,排序算法,可能有整数排序,字符排序,浮点数排序,但它们的排序算法都差不多,不同的就是类型。那我们可以写一个模板,这个模板在编译的时候根据使用的不同,比如使用整型版本,它就会根据模板生成一份针对整型的代码。呵,这是不是就是代码生代码了,一份程序,可能编译后可能生出几份代码来(这也引起了C++里面的代码爆炸的问题,这种方式和C#泛型的方式很不一样,据说java也是这种方式,但我没考究)

除了C++的模板,还有C里面的宏,这宏差不多也是个“模板”,在编译的第一阶段就会全部replace掉。

比如我们定义一个能交换两变量值的宏:

#define SWAP(a,b,type) {type temp;temp = b;b=a;a=temp;}

看看如何使用:

//定义两整型变量

int g = 5,h = 8;

//使用这个宏来交换gh的值,注意,这里并不是方法调用

//通过这个宏的第三个参数可以看出,它适用于多种类型的变量交换

SWAP(g,h,int);

 

上面使用宏可并不是方法调用,和方法调用相比它没有调用时的性能损耗,它在编译器的预处理时期就替换成这样的语句:

int temp;temp = h;h = g;g = temp;

貌似这也是代码生成代码

 

那再看看C# 3.0里一个非常重要的概念----表达式树:

Expression<Func<int, bool>> test = x => x > 1;

就是这么一个Lambda表达式,这样赋值一下编译后:

Expression<Func<int, bool>> test = Expression.Lambda<Func<int, bool>>(Expression.GreaterThan(CS$0$0000 = Expression.Parameter(typeof(int), "x"), Expression.Constant(1, typeof(int))), new ParameterExpression[] { CS$0$0000 });

 

C#编译器却为我们构造了一个树形的数据结构。这是否是元编程?

 

好了就写这么多了,到现在我也没有弄明白什么是元编程,只是一些概念在脑子里忽隐忽现,如是很想把它整理出来,但整理的时候却又非常的凌乱,所以我写在这里作为一期话题,希望各位能讨论讨论,说不定能碰撞出一些火花呢。