【问题标题】:Assign variables value through array in Haxe?通过Haxe中的数组分配变量值?
【发布时间】:2015-07-30 05:49:51
【问题描述】:

如何通过数组将变量abcd的值分配给1234

var a:Int = 0, b:Int = 0, c:Int = 0, d:Int = 0;
var array1:Array<Int> = [a, b, c, d];
var array2:Array<Int> = [1, 2, 3, 4];

for (i in 0...4)
    array1[i] = array2[i]; //this does not work, it assigns array1's elements instead

trace(a); // this prints 0 instead of 1
trace(b); // 0 instead of 2
trace(c); // 0 instead of 3
trace(d); // 0 instead of 4

【问题讨论】:

    标签: arrays variables haxe


    【解决方案1】:

    这不起作用的原因是像Int 这样的基本类型是不可变的。事实上,变量abcd 甚至可能不存在,因为它们永远不会改变。如果您查看 try.haxe.org 上的 JS Source 选项卡,您会注意到它们没有出现在输出中:

    var array1 = [0,0,0,0];
    var array2 = [1,2,3,4];
    var _g = 0;
    while(_g < 4) {
        var i = _g++;
        array1[i] = array2[i];
    }
    console.log(0);
    console.log(0);
    console.log(0);
    console.log(0);
    

    这是对分析仪的优化。

    您需要某种容器类型来完成此操作,例如 classtypedef。这是使用后者的示例:

    class Test {
        static function main() {
            var a:IntContainer = { value: 0 };
            var b:IntContainer = { value: 0 };
            var c:IntContainer = { value: 0 };
            var d:IntContainer = { value: 0 };
    
            var array1:Array<IntContainer> = [a, b, c, d];
            var array2:Array<Int> = [1, 2, 3, 4];
    
            for (i in 0...4)
                array1[i].value = array2[i];
    
            trace(a.value);
            trace(b.value);
            trace(c.value);
            trace(d.value);
        }
    }
    
    typedef IntContainer = {
        value:Int
    }
    

    【讨论】:

      【解决方案2】:

      @Gama11 提供的解决方法是正确的,我们需要一个容器类型,但推理是错误的。 问题不是任何优化的影响

      如果我们运行相关代码的 JS 等效项,我们仍然会得到相同的结果:

      var a = 0, b = 0, c = 0, d = 0;
      var array1 = [a, b, c, d];
      var array2 = [1, 2, 3, 4];
      
      for (var i = 0; i < 4; i++)
          array1[i] = array2[i];
      
      console.log(a); // 0
      console.log(b); // 0
      console.log(c); // 0
      console.log(d); // 0
      

      事实上,这种行为在大多数其他语言中也是一样的。

      原因是,Array 声明采用输入表达式的,而不是它们的引用。这意味着在设置array1 时会评估abcd

      这种行为对于所有的表达式都是一样的,除了函数:

      /*
          variable
      */
      var a = "A";
      var b = a;
      a = "B";
      trace(b); // A
      
      /*
          anon. object
      */
      var a = "A";
      var c = { _c: a };
      a = "C";
      trace(c._c); // A
      
      /*
          Map
      */
      var a = "A";
      var d = ["_d" => a];
      a = "D";
      trace(d["_d"]); // A
      
      /*
          function
          The function body is evaluated every time when it is called.
      */
      var a = "A";
      var f = function () return a;
      a = "F";
      trace(f()); // F <-- notice this
      

      【讨论】:

      • 我并不是说问题是由优化引起的。我添加了该示例以强调存在或不存在的变量对输出没有任何影响,因为它们的值没有改变。也许我没有说得太好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多