如何在Haxe中编写相互递归的函数

3

我试图在Haxe 3中编写一个简单的互递归函数,但是无法使代码编译,因为其中出现的一组相互调用的函数将报告该组中的其他函数未定义。下面是一个最小的示例,其中使用相互定义的函数 odd even 来确定奇偶性。

static public function test(n:Int):Bool  {
    var a:Int;
    if (n >= 0) a = n; else a = -n;

    function even(x:Int):Bool {
        if (x == 0)
            return true;
        else
            return odd(x - 1);
    }
    function odd(x:Int):Bool {
        if (x == 0)
            return false;
        else
            return even(x - 1);
    }
    return even(a);
}

尝试编译为neko时出现以下问题:
../test.hx:715: characters 11-14 : Unknown identifier : odd
Uncaught exception - load.c(181) : Module not found : main.n

我尝试在Haxe3中像在c/c++中那样先声明even之前的odd, 但是似乎这是不合法的。如何定义像上面那样相互递归的函数?这是否可能?请注意:我想让oddeven都成为局部函数,包裹在全局可见的test函数中。谢谢。
1个回答

3

与其使用function myFn() {}语法来定义一个局部变量,你可以使用myFn = function() {}语法。这样,你就能在使用函数之前声明函数类型。

你的代码应该像这样:

static public function test(n:Int):Bool  {
    var a:Int;
    if (n >= 0) a = n; else a = -n;

    var even:Int->Bool = null;
    var odd = null; // Leave out the type signiature, still works.
    even = function (x:Int):Bool {
        if (x == 0)
            return true;
        else
            return odd(x - 1);
    }
    odd = function (x:Int):Bool {
        if (x == 0)
            return false;
        else
            return even(x - 1);
    }
    return even(a);
}

这能够实现是因为Haxe只需要知道evenodd存在,并在使用之前设置为某些值(即使为null)。我们知道,在它们被调用之前,我们会将它们都设置为可调用的函数。
在try haxe上查看:http://try.haxe.org/#E79D4

1
谢谢,Jason。这很接近了。但我仍然得到一个错误,抱怨odd没有被初始化。../test.hx:725: characters 19-22 : Local variable odd used without being initialized Uncaught exception - load.c(181) : Module not found : main.n - thor
抱歉,我应该测试一下那段代码。应该是 var even=nullvar odd=null。Haxe 太过严谨了,这反而不好。我会修改我的回答。 - Jason O'Neil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接