Function lua函数引用可以用作表键吗?

Function lua函数引用可以用作表键吗?,function,reference,lua,key,lua-table,Function,Reference,Lua,Key,Lua Table,一个Lua新手在这里。我可以将函数引用作为键存储在Lua表中吗?类似于此: local fn = function() print('hello') end local my_table = {} my_table[fn] = 123 这似乎很好,但我不知道是否可以依赖函数引用的唯一性。一旦函数引用超出范围,Lua能否重用它们?这会产生任何问题吗?或者由于某种原因,这被认为是一种不好的做法吗?是的。我在lua中遇到的最好的事情之一是任何作为引用的属性 您在表中使用键的方式没有问题 从…起 Lu

一个Lua新手在这里。我可以将函数引用作为键存储在Lua表中吗?类似于此:

local fn = function() print('hello') end
local my_table = {}
my_table[fn] = 123

这似乎很好,但我不知道是否可以依赖函数引用的唯一性。一旦函数引用超出范围,Lua能否重用它们?这会产生任何问题吗?或者由于某种原因,这被认为是一种不好的做法吗?

是的。我在lua中遇到的最好的事情之一是任何作为引用的属性

您在表中使用
键的方式没有问题

从…起 Lua中的表既不是值也不是变量;它们是对象。您可以将表视为动态分配的对象;您的程序只处理对它们的引用(或指针)。幕后没有隐藏副本或创建新表

在您的示例中,您没有向函数传递任何参数,因此基本上,在您的示例中,将函数作为程序中的引用是没有用的。另一方面,类似这样的情况:

fn1 = function(x) print(x) end
fn2 = function(x) print("bar") end
t[fn1] = "foo"
t[fn2] = "foo"
for i, v in pairs(t) do i(v) end
确实有它的用途

一旦函数引用超出范围,Lua能否重用它们

只要父表在范围内,就可以。由于表是创建和操作的,而不是复制的,所以函数引用不可能从表索引内存中被弃用我也会在试用后编辑这个答案。

这会产生任何问题吗?或者由于某种原因,这被认为是一种不好的做法吗

这被认为是一种糟糕的做法,因为熟悉其他语言的用户,如
C
python
等,在阅读表格时往往会想到数组。在你没有这样的担心,该计划将工作完美

我不知道是否可以依赖函数引用的唯一性


为什么?

可以这样做,
函数将保留在内存的相同位置,直到它被(垃圾收集器)销毁

您可以在交互式
lua中尝试:

> fn = function() print('hello') end
> print(fn)
function: 0x9d058d0

> fn2 = function() print('hello') end
> print(fn2)
function: 0x9d05ee8

> fn2=fn
> print(fn2)
function: 0x9d058d0

> print(function() print('hello') end)
function: 0x9d068a8

> print(function() print('hello') end)
function: 0x9d06bf8
请记住,如果
fn
local
,则当超出范围时,它将被垃圾收集。在您的情况下,这不应该是一个问题,因为
my_table
在同一块中是
local
。看

这似乎很好,但我不知道是否可以依赖函数引用的唯一性

每个
function()end
语句都会创建一个新的闭包。如果函数的实际代码来自同一个构造函数,则该代码将被重用:

for i=1,100 do
    t[function() print(i) end] = i -- this function body will be reused
end
但每一个结尾都是独一无二的,这对你的参考很重要

一旦函数引用超出范围,Lua能否重用它们


Lua不会收集
fn
,只要它被用作
my_表中的键即可。如果
my_table
也超出范围,导致表和函数都被收集,那么Lua重用引用不会影响您。因此,无论哪种方式,您都很好。

函数引用的唯一性取决于Lua版本

Lua 5.2手册上说:
函数定义不能创建新值;如果新功能没有明显差异,则可能会重复使用某些以前的值

例如:

-- 10 different function references on Lua 5.1
-- The same function reference for Lua 5.2
local j
for i = 1, 10 do
   print(function() print(j) end)
end

-- 10 different function references for any Lua version
for i = 1, 10 do
   print(function() print(i) end)
end

因此,规则是:创建不同的闭包以获得不同的引用。

谢谢您的详细回答!非常感谢!我对函数引用的唯一性表示怀疑,因为可能会有一种罕见的情况,即两个函数具有相同的主体,Lua解释器可能会决定将其作为单个引用以节省内存,就像大多数语言中的空对象和相同字符串一样。尽管如此,在大多数项目中不应出现两个职能机构相同的情况。另一个原因是Lua可以对其他函数使用相同的哈希代码(打印函数或调用tostring(fn))吗。但正如您所阐明的,除非它是gc'ed,否则这是不可能的。即使是同一个主体,只要您为它们使用单独的
name
s,它们将被分配新的引用。@BackinaFlash这通常是不正确的。5.1官方口译员也是如此;但不适用于5.2。我相信这取决于个人的实施。谢谢你!这是一件重要的事情。但是我不希望在我的项目中有两个具有相同实体的函数,所以这不重要。另外,如果我们在不同的范围内创建具有相同实体的两个函数,比如在不同的表中创建值,那么它们确实会得到唯一的引用,这样就解决了相同实体函数的任何可能性。在luajit中打印nil?!