大多数OOP语言将一个类实现为垃圾回收引用。但是,与常规引用类型相比,基于任务(协程)的实现可能具有多个优点:
-方法调用是传递点,而不是单独的函数。像这样的协程直接
将方法调用集成到其控制流中。
-然后,只需拦截传输点即可实现多态。这实际上是一个 比OOP动态调度灵活得多(如果> 1,它将变得很麻烦 派遣参数)。
-协程实例作为对话框对象返回到调用方,该对话框对象包含当前架构节点,并交换参数并在每个继续点上返回。这个对象实际上也是对协程对象的弱引用。
-因为方法调用已集成到控制流中,所以协程可以为有效的方法调用序列声明上下文无关的语法,这些语法可以是 在服务器端进行静态检查,并在运行时通过简单的分析表在客户端进行检查。
作为这种类型如何工作的示例,我会使用伪adad语法勾勒出一个窗口的轮廓:
cotask interface window is
-- the schema declares a context-free grammar for the valid sequences of method calls
-- on a window. transfer points (accept branches) in an implementor must follow the
-- syntax. this can easily be checked at compile-time if certain rules are applied.
schema is
start = createWindow drawWindow {stuff} closeWindow;
stuff = doThisWithTheWindow | doThatWithTheWindow;
-- entries (methods) are treated as terminals in the syntax above. the exported entries
-- are the alphabet of the schema syntax.
entry createWindow (int x0,y0,w,h);
entry drawWindow();
entry doThisWithTheWindow (P p) return R;
entry doThatWithTheWindow (Q q) return S;
end window;
cotask myWindow implements window is
-- we assume a rule that a nonterminal is implemented on a function with the same name
procedure stuff(out boolean continue) is
begin
select
accept doThisWithTheWindow(p:P) return R do ... continue := true; end;
or accept doThatWithTheWindow(q:Q) return S do ... continue := true; end;
else continue := false;
end
end stuff;
begin
-- an accept swaps context back to the caller and continues on the branch body on the
-- corr entry
accept createWindow(int x0,y0,w,h) do ...end;
accept drawWindow() do...end;
boolean continue;
loop
stuff(continue);
exit when not continue;
end loop;
accept closeWindow() do...end;
-- the return here closes the dialog and deletes the context. this is only allowed
-- on a final node such as closeWindow()
end myWindow;
procedure myWindowClient() is
myWindow W;
begin
W.create(0,0,1024,768);
W.draw();
loop
W.doThisWithTheWindow(p);
W.doThatWithTheWindow(q);
exit when someTwitThrowsABrickThruTheWindow;
end loop;
W.close();
end myWindowClient;
多态性是通过重写一个或多个accept()分支来实现的。一个类型可以实现几个这样的接口,作为不相交模式的并集(每个接口都被视为不相交),然后基本类型将成为实现者类型中非终结符的替代。诸如stuff()之类的函数也可以被重写为类型参数。
当然,不利的一面是系统必须为协程创建一个上下文,并且通常无法事先为该上下文确定最佳存储大小。方法调用还需要上下文交换,这比简单的函数调用要慢(并且在客户端也有额外的类型验证开销)。有人知道这样做的语言吗?无论哪种方式,您的想法都会受到赞赏:)... thx