【问题标题】:Variable number of arguments in HaxeHaxe 中可变数量的参数
【发布时间】:2017-09-13 21:10:04
【问题描述】:

我正在寻找一种在 Haxe 中执行此类操作的方法:

function foo(...args)  
{  
  for (arg in args)
  {
    ...
  }
}

附近有人可以帮助我吗?

【问题讨论】:

标签: parameters haxe


【解决方案1】:

这个问题很老了,所以,我作为一个文档来回答。 自 4.2 起,Haxe 支持休息参数:


function logAll(...arguments : String)
{
   for(arg in arguments)
      trace(arg);
}

【讨论】:

    【解决方案2】:

    如果你真的需要,有一种方法:Reflect.makeVarArgs。这是非常无类型的,因此我建议您首先考虑使用有类型的替代方案。

    就我个人而言,我可能只会将其用于调试或在由于某些其他原因而已经无类型的代码中。

    例子:

    static function _foo(args:Array<Dynamic>)
    {
        return "Called with: " + args.join(", ");
    }
    
    static var foo:Dynamic = Reflect.makeVarArgs(_foo);
    
    [...]
    
    trace(foo(1));
    trace(foo(1, 2));
    trace(foo(1, 3, 3));
    

    (see it in Try Haxe)

    【讨论】:

    • makeVarArgs 的通用版本适用于其余参数遵循相同类型的情况。即如果_foo 只接受Ints 的数组。
    【解决方案3】:

    Haxe 没有其他参数,主要是因为这些参数本质上是无类型的,并且该语言应该有助于进行类型化以获得最安全的代码。编译器可以检查和优化键入的代码。编译时错误更多,运行时错误更少。

    仍然可以通过几种方式实现与其余参数相同的结果,具体取决于您要查找的内容;该函数是只接收值还是对象?

    最直接的方法是使用Any 类型和Reflect

    function loop(props:Any) 
    {
        for (prop in Reflect.fields(props))
        {
            trace(prop, Reflect.field(props, prop));
        }
    }
    // usage: 
    loop({name: "Jerson", age: 31});
    

    您可以只使用带有值的数组,因此您在使用时还需要使用数组:

    static function loop(values:Array<Any>) 
    {
        for (i in 0...values.length)
        {
             trace(i, values[i]);
        }
    }
    //usage:
    loop(["Jerson", 31]);
    

    如果你在实现中不喜欢这个数组,你也可以使用这个古怪的函数,我不建议这样做,只是提供一个想法。

    function loop<A,B,C,D,E,F>(?prop1:A, ?prop2:B, ?prop3:C, ?prop4:D, ?prop5:E, ?prop6:F) 
    {
        var props:Array<Any> = [prop1,prop2,prop3,prop4,prop5,prop6];
        for (i in 0...props.length)
        {
             trace(i, props[i]);
        }
    }
    // usage: 
     loop3("Jerson", 31);
    

    在此处尝试这些示例:https://try.haxe.org/#Be3b7

    还有macros for rest arguments,如果你熟悉宏就可以了。请注意,这将在编译时进行跟踪,目前不会在输出源中生成跟踪。

    import haxe.macro.Expr;
    
    macro static function loop(e1:Expr, props:Array<Expr>)
    {
        for (e in props) 
        {
            trace(e);
        }
        return macro null;
    }
    // Usage:
    loop("foo", a, b, c);
    

    当然最好的建议是不要太动态以保持类型安全,但这应该会让你继续前进。

    【讨论】:

    • 感谢您的回答!它对我有帮助的阵列解决方案。我正在实现一个键盘输入管理器,我需要这样做:Keyboard.bind("jump", Key.UP, Key.W); 只是为了更好地阅读。但写作:Keyboard.bind("jump", [Key.UP, Key.W]); 是最接近的方式。
    • 在这种情况下,我当然会使用数组。数组已经有一个 API 和工具来处理它们。
    • @JersonLaTorre 我可能会为此使用宏。
    • 使用宏方法,如何将其余参数限制为单一类型,即Ints?如果 expr 不是您期望的类型,如何因编译错误而失败?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多