LUA:避免引用传递

我刚开始学习 LUA,我有一个问题,不确定正确的解决方式。当我将 Defold 的 vmath.vector3 传递给函数时,它似乎是通过引用传递的,因此被修改。

如果我将其乘以任何东西,这个问题就解决了。

但是,还有另一种更正确的解决方法吗?我不想修改作为参数传递的原始向量。

function M.get_nearest_tile(x, y)
    if y then -- 如果有两个输入,使用 x 和 y
        x = math.floor(x / M.TILE_SIZE)
        y = math.floor(y / M.TILE_SIZE)
        return x, y
    else -- 如果只有一个输入,使用向量
        local vec = x * 1 -- 乘以 1 以避免修改真实向量
        vec.x = math.floor(vec.x / M.TILE_SIZE)
        vec.y = math.floor(vec.y / M.TILE_SIZE)
        return vec.x, vec.y
    end
end
点赞
用户1442917
用户1442917

你已经在 else 分支中有一个解决方案:在对向量进行“修改”操作之前,你需要创建向量的副本。

在其他选项方面,可能有一种使用代理表的方法,但这将比创建副本要复杂得多。

2018-11-13 21:36:04
用户3574628
用户3574628

因为你返回了 xy 两个值,所以你可以在不修改任何表格的情况下以相同方式实现两个分支:

function M.get_nearest_tile(x, y)
    local newX, newY
    if y then -- 如果有两个输入,使用 x 和 y
        newX = math.floor(x / M.TILE_SIZE)
        newY = math.floor(y / M.TILE_SIZE)
    else -- 如果只有一个输入,按照向量使用
        newX = math.floor(x.x / M.TILE_SIZE)
        newY = math.floor(x.y / M.TILE_SIZE)
    end
    return newX, newY
end
2018-11-13 23:20:34
用户1266551
用户1266551

Defold 提供了一些特殊的数据结构,在游戏开发中非常有用:

  • vector3 - vmath.vector3(x,y,z),用于描述 3D 坐标系中的位置或方向
  • vector4 - vmath.vector4(x,y,z,w),用于颜色、色调等 (红、绿、蓝、透明度)
  • quat - vmath.quat() 描述旋转
  • matrix4 - vmath.matrix4() 4x4 值的矩阵。在视图和投影矩阵等方面非常有用

以上所有数据结构都被 Defold 游戏引擎使用,但你也会在其他游戏引擎中找到同样类型的数据结构。

以上数据结构有一个共同点:它们都是 Lua 类型的 userdata

print(type(vmath.vector3())) -- "userdata"

用户数据始终按引用传递,这就是你描述行为的原因。 但是,Defold 提供了制作副本的方法:

local copy = vmath.vector3(original) -- 复制 vector3 'original' local copy = vmath.vector4(original) -- 复制 vector4 'original' local copy = vmath.quat(original) -- 复制 quaternion 'original' local copy = vmath.matrix4(original) -- 复制 matrix4 'original'

2018-11-14 05:17:35