简体   繁体   English

如何在Lua中动态生成函数?

[英]How to dynamically generate functions in Lua?

If I have a table {field1=1,field2=0} (0: ascending order, 1: descending order)如果我有一个表{field1=1,field2=0} (0:升序,1:降序)

I want to get a function:我想得到一个函数:

function(x,y)
  return x.field1 < y.field1 --there 0:'<',1:'>=' 
end

field1 in the table and the sorting rule can be injected in the function.表中的field1和排序规则可以在函数中注入。

How to generate this code dynamically?如何动态生成此代码?

Let's talk about more than just the code generation approach!让我们讨论的不仅仅是代码生成方法! As in the question, consider the need of a function:与问题一样,请考虑需要一个函数:

function (x, y)
   return x.field1 --[[ < or >= ]] y.field1
end

For the sake of the examples assume that we have global variables:为了示例,假设我们有全局变量:

FIRST = {field1 = 3}
SECOND = {field1 = 5}

Branching分枝

The simplest solution (perhaps also the most typical?) that comes to my mind is a verbose if :我想到的最简单的解决方案(也许也是最典型的?)是冗长的, if

function foo (x, y, o)
   if o == nil or o == "asc" then
      return x.field1 < y.field1
   end
   if o == "dsc" then
      return x.field1 >= y.field1
   end
   error("Unknown option")
end

-- Example:
foo(FIRST, SECOND, "asc")
foo(FIRST, SECOND, "dsc")

Note that early returns make else unnecessary in this case but it might not always be true.请注意,在这种情况下,提前返回使else变得不必要,但它可能并不总是正确的。

Anonymous function匿名函数

But, hey, what's that?但是,嘿,那是什么? What if rather than a string option we pass something more bizarre like... something that can be called?如果我们传递的不是字符串选项而是更奇怪的东西,比如……可以调用的东西怎么办? Let's go with a simple function this time:这次我们用一个简单的函数:

local asc = function (a, b) return a < b end
local dsc = function (a, b) return a >= b end

function bar (x, y, compare)
   compare = compare or asc
   return compare(x.field1, y.field1)
end

-- Example:
bar(FIRST, SECOND, asc)
bar(FIRST, SECOND, dsc)
bar(FIRST, SECOND, function (a, b) return a < b end)

Higher-order function高阶函数

The previous example doesn't really look that good with a such simple operation, but let's take it as a base and let's create a function that will return us the desired function:使用如此简单的操作,前面的示例看起来并不是那么好,但是让我们以它为基础,让我们创建一个函数来返回我们所需的函数:

function make (compare)
   return function (x, y) return compare(x.field1, y.field1) end
end

-- Example:
local asc = make(function (a, b) return a < b end)
local dsc = make(function (a, b) return a >= b end)
asc(FIRST, SECOND)
dsc(FIRST, SECOND)

Actual generation实际发电量

Now then, let's try something closer to code generation.现在,让我们尝试一些更接近于代码生成的东西。 Lua gives us the ability to load chunks as we go with load* function family. Lua 使我们能够在使用load*函数系列时加载块。

Please note that load in 5.1 is different from load in 5.2 or load in 5.3 .请注意, load在5.1是从不同的load在5.2load在5.3 In 5.1 you want to useloadstring instead of load .在 5.1 中,您想使用loadstring而不是load

function generate (op)
   return load(string.format("return function (x, y) return x.field1 %s y.field1 end", op))()
end

-- Example:
local asc = generate("<")
local dsc = generate(">=")
asc(FIRST, SECOND)
dsc(FIRST, SECOND)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM