Lua 中复制表格的值会改变原始值

我想复制一个简单的表格,但是每当我改变复制的表格时,原始表格也会改变,这很奇怪。

function tablelength(T)
  local count = 0
    for _ in pairs(T) do count = count + 1 end
  return count
end

board = {}
print("board: "..tablelength(board))

newBoard = board
newBoard[tablelength(newBoard) + 1] = 1
print("board: "..tablelength(board))
newBoard[tablelength(newBoard) + 1] = 1
print("board: "..tablelength(board))

输出结果:

board: 0
board: 1
board: 2
点赞
用户6632736
用户6632736

newBoard = board 只是创建了一个新的引用 newBoard,在 board 之后,指向同一个由 {} 创建的表格。

如果你想要一个全新的表格,你需要进行 _深度复制_。

就像这样:

local function deep_copy( tbl )
    local copy = {}
    for key, value in pairs( tbl ) do
        if type( value ) ~= 'table' then
            copy[key] = value
        else
            copy[key] = deep_copy( value )
        end
    end
    return copy
end

这是一个简单的实现,不会复制元表和键是表格的键(Lua 中是可能的),以及包含对自身的引用的表格,但对于你的目的而言可能已经足够了。

更多阅读:https://www.lua.org/pil/2.5.html,从第二段开始。

P.S. 一种不太 naïve 的实现,基于http://lua-users.org/wiki/CopyTable

local function deep_copy( original, copies )
    if type( original ) ~= 'table' then return original end

    -- original 是一个表格。
    copies = copies or {} -- 这是已经复制的表格缓存。

    -- 这个表格已经被复制了。
    if copies[original] then return copies[original] end

    -- 我们需要深度复制之前没有深度复制的表格。
    local copy = {}
    copies[original] = copy -- 在缓存中存储对已复制表格的引用。
    for key, value in pairs( original ) do
        local dc_key, dc_value = deep_copy( key, copies ), deep_copy( value, copies )
        copy[dc_key] = dc_value
    end
    setmetatable(copy, deep_copy( getmetatable( original ), copies) )
    return copy
end
2020-09-27 07:34:17