【发布时间】:2015-02-18 17:25:42
【问题描述】:
我是 Ceylon 的新手,目前正在探索如何将一些用 TypeScript(主要是 JavaScript)编写的现有软件移植到 Ceylon,以便它可以在 JavaScript 引擎和 JVM 上运行。
有人知道如何在 Ceylon 中编写类似 Java 的代码吗:
public class Engine { ... } // Some given class definition
public interface Cont extends Callable1<Cont,Engine> {}
其中Callable1<Y,X> 是 Ceylon 的 Callable<Y,[X]> 的 Java 等价物。
这个想法是Cont 的实例,比如名为c,将是一个返回另一个Cont 或null 的函数。
在 Java 中,使用它的代码如下所示:
// Somewhere
public static void exec(Cont c, Engine e) {
while (c != null) c = c.call(e);
}
(这本质上是一个蹦床,每个被调用的函数都返回延续,或者在计算完成时返回null。)
另外,在锡兰我想将函数作为 Cont 的实例传递。
阅读回复后,我提出了以下解决方案,它使用正确的结果类型(Cont? 而不是Anything)和null-testing(用于性能):
shared interface Cont { shared formal Cont? call(Engine e); }
// A wrapper class for an actual continuation function
class ContWrap(Cont?(Engine) fun) satisfies Cont {
shared actual Cont? call(Engine e) => fun(e);
}
shared Cont wrap(Cont?(Engine) fun) {
return ContWrap(fun);
}
// Somewhere
shared void exec(variable Cont? cont) {
while (exists cc = cont) {
cont = cc.call(this);
}
}
这适合我,代价是每次都创建一个额外的小对象,并通过 wrap 传递函数。
【问题讨论】:
-
如果
wrap(fun)和ContWrap(fun)一样,为什么不直接做后者呢? -
@gdejohn,这纯粹是出于设计原因:
ContWrap是实现特定行为的辅助内部类,因此用户不应该意识到它(当然也不应该编写依赖于它)。另一方面,函数wrap是API 的一部分(即,它是一个工厂函数)。
标签: ceylon