我是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
。)
此外,在Ceylon中,我想将函数作为Cont。
的实例传递阅读完回复后,我提出了以下解决方案:使用正确的结果输入(Cont?
代替Anything
)和null
- 测试(性能) ):
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
传递函数。
答案 0 :(得分:3)
Callable
的自定义实施已discussed,但目前还不可行。但是,你并不需要那样。
shared class Engine() {
// ...
}
shared interface Continuation {
shared formal Continuation? call(Engine engine);
}
shared void execute(variable Continuation? continuation, Engine engine) {
while ((continuation = continuation?.call(engine)) exists) {}
}
object continuation satisfies Continuation {
call(Engine engine) => null;
}
// usage
execute(continuation, Engine());
// usage in 1.2 with inline object expression
execute(object satisfies Continuation { call(Engine engine) => null; }, Engine());
由于Continuation
没有(不能)满足Callable
,因此您无法传递函数。但是在即将发布的版本(1.2,现在通过GitHub提供)中,您至少可以使用inline object expressions。
请注意,这不是惯用的Ceylon,只是来自Java的直接翻译。
答案 1 :(得分:1)
这似乎是编译,但它看起来非常可怕:
class Engine() {}
Anything(Engine) foo(Engine e) {
return foo;
}
// Somewhere
variable Anything(Engine)? f = foo;
while (is Anything(Engine)(Engine) f2=f) {
f = f2(e);
}