在脚本语言中一个取巧实现 OO 的方法
今天,脚本编译器连同前段写的虚拟机全部完工了,很有成就感。
跟 lua 一样,复杂的数据类型我只支持了 table ,这个 table 即可以做 array 也可以做 hash_map 用。一般用 lua 的人都会用 table 去模拟 class 。lua 只对这个做了非常有限的扩展:在 lua 的文档中,我们可以看到
function t.a.b.c:f (...) ... end 可以等同于 t.a.b.c.f = function (self, ...) ... end
就我用 lua 的经验,这个转换用途不是特别大,只是少写个 self 而已。
这次我自己设计脚本语言,针对脚本支持 OO 的问题,特别做了些改进。
看一段脚本,这是用我自己定义的语言写的:
A={};
function A.sum (_self)
{
return .a + .b;
}
function A.print (_self)
{
print(->sum());
return _self;
}
a={A,
.a=100,
.b=200,
};
a->print();
这是一个非常简单的例子。全局函数 print 是我测试程序注册的。我是这样想的,把成员函数放到一张 table 里。这里是 A.sum 和 A.print 两个,放进了 A 这个 table。 然后我创建了对象 a={A,.a=100,.b=200};
这里默认 a[0] 放的是 vtbl, 就是 table 初始化队列的第一项。 如果用 -> 来调用函数的话,比如 a->sum() 就在编译时转化成 a[0]->sum(a)
在函数里,如果用 . 开头的变量,就自动展开成 _self.x 。这个 _self 是函数的第一个参数。 需要在函数定义中明确写出来,但是名字可以随便。不过名字必须用 _ 开头。 同理 ->sum() 就展开成 _self->sum()
所以,在一个成员函数中,我们可以看到所有以 . 开头的变量操作都可以看成是成员变量。以 -> 开头的函数调用,可以看成是成员函数调用。当然,这里所有成员函数都和 C++ 中虚函数的概念相同。如果需要给 A 类写个静态函数,即不需要传 self 的话,可以用 A.static_func() 这样调用了。
我在这里用名字来强制约定变量的类型。_ 开头的全部是局部变量,否则就是全局。这样可以方便很多编译的工作,也让代码比较容易读,在弱类型检查的脚本里,还可以避免一些笔失误。
Comments
Posted by: Atry | (13) January 27, 2006 04:35 AM
Posted by: Atry | (12) December 6, 2005 05:38 PM
Posted by: Atry | (11) December 6, 2005 05:25 PM
Posted by: Cloud | (10) December 6, 2005 04:32 PM
Posted by: Atry | (9) December 6, 2005 04:28 PM
Posted by: Cloud | (8) December 6, 2005 12:54 PM
Posted by: Atry | (7) December 6, 2005 09:32 AM
Posted by: Cloud | (6) December 5, 2005 08:21 PM
Posted by: Atry | (5) December 5, 2005 06:18 PM
Posted by: Cloud | (4) December 5, 2005 05:00 PM
Posted by: Anonymous | (3) December 5, 2005 03:57 PM
Posted by: starimpact | (2) December 5, 2005 02:02 PM
Posted by: dawndu | (1) December 5, 2005 12:44 PM