Lua中一种更好的将多个返回值分配给表键的方法
2017-1-2 3:42:29
收藏:0
阅读:132
评论:2
假设我有一个返回多个值的函数。我刚好在使用LÖVE的(Image):getDimensions。这返回了两个值,我知道它们是 width,height。我想将它们分配到一个新表中,作为一个数组。我想要的是已命名(字符串)键。例如,我想将 getDimensions() 函数的返回值分配到一个新表中,其中 width 和 height 都是键。
我知道以下代码可以工作...
image = {}
image.data = love.graphics.newImage('myimage.png')
image.size = {}
image.size.width, image.size.height = image.data:getDimensions()
我在思考是否有任何语法糖可以使用,或者使用标准库函数来启用更接近以下代码的语法...
image.size = { width, height = image.data:getDimensions() }
我知道上面一句话不起作用,同时我尝试了许多变体,包括各种使用unpack()的尝试。我对Lua不熟悉(现在约两天),所以可能有另一种标准函数或最佳做法,可以将一个键的表关联到类似于数组的表中。谢谢!
点赞
用户4342563
使用类构造,我得出以下结果...
Size = {}
Size.mt = {}
Size.prototype = { width = 0, height = 0 }
function Size.new (dimensions)
local size = setmetatable({}, Size.mt)
if dimensions ~= nil and type(dimensions) == 'table' then
for k,v in pairs(dimensions) do
size[k] = v
end
end
return size
end
Size.mt.__index = function (t, k)
if k == 'width' or k == 'height' then
rawset(t, k, Size.prototype[k])
return t[k]
else
return nil
end
end
Size.mt.__newindex = function (t, k, v)
if k == 1 or k == 'width' then
rawset(t, 'width', v)
elseif k == 2 or k == 'height' then
rawset(t, 'height', v)
end
end
然后我可以以多种方式初始化一个大小对象
使用多个返回值:
image.size = Size.new{image.data:getDimensions()}image.size = Size.new(table.pack(image.data:getDimensions())
使用默认值:
image.size = Size.new()image.size = Size.new{}image.size = Size.new({})
使用混合数组和哈希表:
image.size = Size.new({height=20, width=30})image.size = Size.new({height=20, 30})
这种方法与 Egor 的方法(实用函数)相比有优劣之分,如果没有一个简单的语法技巧或我不知道的现有函数的话,我考虑采用 Egor 的方法。
优点:
- (个人)在 Lua 中学习 OO 构造的经验
- 我可以限制表中实际键的数量,同时允许通过扩展
__index和__newindex中接受的值来添加 'synonyms'(同义词)这些键 - 明确定义表中的字段,无需担心使用通用工具函数时需要同步键表和值表。
缺点:
- 需要为每个想要使用此行为的数据结构重复此模式
- 代价高,对于消费者来说,这相当于非常小的差异所产生的大量开销
我相信我可以随着时间的推移使这种方法更加健壮,但是我会感谢任何反馈。
2017-01-01 22:54:06
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

你可以编写自己的函数:
local function set_fields(tab, fields, ...) -- fields是一个字段名称的数组 -- (使用空字符串跳过相应位置的值) local values = {...} for k, field in ipairs(fields) do if field ~= "" then tab[field] = values[k] end end return tab end local function get_fields(tab, fields) local values = {} for k, field in ipairs(fields) do values[k] = tab[field] end return (table.unpack or unpack)(values, 1, #fields) end用法示例#1:
image.size = set_fields({}, {"width", "height"}, image.data:getDimensions())用法示例#2:
在运行时交换值!
local function get_weekdays() return "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" end -- 我们想以不同的顺序保存返回的值 local weekdays = set_fields({}, {7,1,2,3,4,5,6}, get_weekdays()) -- 现在weekdays包含{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}用法示例#3:
local function get_coords_x_y_z() return 111, 222, 333 -- 点的x、y、z end -- 我们想在地平面上获取点的投影 local projection = {y = 0} -- projection.y将被保留,projection.x和projection.z将被修改 set_fields(projection, {"x", "", "z"}, get_coords_x_y_z()) -- 现在projection包含{x = 111, y = 0, z = 333}用法示例#4:
如果
require("some_module")返回一个具有许多函数的模块,但您只需要其中的几个函数:local bnot, band, bor = get_fields(require("bit"), {"bnot", "band", "bor"})