如何获取尚未声明但将很快声明的变量?

时间:2015-10-03 14:44:34

标签: lua

如何获取尚未声明的变量?

这是一个简单的例子:

a = b
b = 123

我想从这两行中得到的是a<< 123。但是,它显然不起作用。

我知道获得答案a = 123的简单方法是剪切第一行并将其粘贴到低于第二行。

但是我遇到了一些问题。我需要一些功能,例如' WillDeclaredVar()'我可以这样使用:

a = WillDeclaredVar(b)
sheepCount = 123
b = sheepCount
print(a)

所以我可以得到答案' 123'。

或者有任何内置函数可以让我做类似的事情吗?

===

我认为蒂姆劳给出的联系并不能说明我的情况。关键是如何获得尚未宣布的变量'。

===

添加实际代码:

triggerCount = 0 -- Counting number of 'Trigger' function
local Trigger = function (t)
triggerCount = triggerCount + 1
return Trigger (t)
end


-- following Triggers are same as while statement.
-- following Triggers doing: Add 1 MarineCount until get 64000 MarineCount



Trigger { -- Here the Trigger function. Now triggerCount = 1.
    players = {P1}
    actions = {
        SetDeaths(P1, Add, 1, "Terran Marine")
    },
flag = {preserved},
}
Portal(LoopStart);
-- function Portal(VariableName) returns VariableName = triggerCount. So LoopStart = 1.

Trigger { -- Now triggerCount = 2.
    players = {P1}
    actions = {
        LinkList(LoopEnd, LoopStart);
-- function LinkList(From, To) changes 'From' Trigger's next pointer to the 'To' Trigger.
-- But now the problem happens. Because 'LoopEnd' is not declared yet.
    },
flag = {preserved},
}


Trigger { -- Now triggerCount = 3.
    players = {P1}
    conditions = {
        Deaths(P1, Exactly, 64000, "Terran Marine");
    }
    actions = {
        _LinkList(LoopEnd);
        -- Reset LoopEnd's next pointer(= LoopEscape) if MarineCount hits 64000
    },
flag = {preserved},
}
Portal(LoopEnd); -- LoopEnd = 3.
  1. 更改触发顺序将破坏触发逻辑(while语句)。

  2. 我想要的只是编码很容易。坦率地说,我不需要解决这个问题(获得未申报的var)。我可以想象一些避免它的方法。但如果我使用这些方法,那么编码工作将非常复杂,编码的难度将大大增加。困难让我在最近几个月停止编码。

2 个答案:

答案 0 :(得分:1)

  

如何获取尚未声明的变量?

旅行时间短,你不能。

您的示例代码无法解释问题的动机,因为:

int main(int argc, const char * argv[]) {
// insert code here...
int arr[4] = {2,1,4,3};
int max=4;
int count=0;

for(int i=0;i<4;i++)
{
    while(count<4)
    {
       if(arr[count]>=max)
       {
           printf("*");
       }
        else
        {
            printf(" ");
        }
        count++;
    }
    count=0;
    max--;
    printf("\n");


}

return 0;
}

可以简单地重新安排到这个:

a = WillDeclaredVar(b)
sheepCount = 123
b = sheepCount
print(a)

如果您展示了您尝试解决的实际问题(避免使用XY problem),那么回答您的问题会更容易。

然而,如上所述,我们可以注意到一些事情。

首先,您需要区分声明变量和赋予其值。在Lua你可以说:

sheepCount = 123
b = sheepCount
a = WillDeclaredVar(b)
print(a)

local b 声明为一个局部变量,它可能会在堆栈框架中为它创建一个槽,并允许您在它给它一个值之前将闭包绑定到它。但是,行:

b

a = WillDeclaredVar(b) 当前所拥有的值传递给WillDeclaredVar,并且由于{b无法追溯更改a {1}}被分配了一个新值。这永远不会发生。 ba都不知道WillDeclaredVar存在,他们会在通话点收到它包含的值。

然而,您可以将变量b绑定到一个闭包,该闭包将在需要时获取b的当前值。

b

另一种方法是将-- declare b before giving it a value, aka "forward reference" local b a = function() return b end sheepCount = 123 b = sheepCount print(a()) -- call a to get b's current value 作为全局变量,这实际上只是环境表中的一个键,所以你可以说:

b

a = WillDeclaredVar('b') 成为可以在需要时获取当前值a的对象。

但是,这些都不支持这种语法:

__ENV['b']

print(a) 需要是一个函数,在需要时查找a的值,而不是简单地保存先前计算的值。您可以在此特定实例中执行此操作(即b需要可转换为字符串),方法是创建实现a的代理对象。

__tostring

输出:

function WillDeclaredVar(variableName)
    local proxy = { environment = _ENV or _G, variableName = variableName }
    return setmetatable(proxy, {
        __tostring = function(proxy)
            return proxy.environment[proxy.variableName]
        end
    })
end

-- a will compute a value based on the current value of b when needed
a = WillDeclaredVar('b')
sheepCount = 123
b = sheepCount
print(a)

答案 1 :(得分:0)

要使var1成为var2var1 = ReferenceF or var2的参考(请注意“ReferenceFor”中的空格!)

do
   local values, references, reference_flag = {}, {}
   setmetatable(_G, {
      __index = function (_, name)
         if name == 'ReferenceF' then
            reference_flag = true
         elseif reference_flag then
            reference_flag = false
            return {[references] = name}
         elseif references[name] then
            return _G[references[name]]
         else
            return values[name]
         end
      end,
      __newindex = function (_, name, val)
         if type(val) == 'table' and val[references] then
            references[name] = val[references]
         else
            values[name] = val
         end
      end
   })
end

a = ReferenceF or b  -- a is Reference For b
b = ReferenceF or c  -- b is Reference For c
sheepCount = 123
c = sheepCount
print(a, b, c)  --> 123 123 123