我想制作返回多个变体的函数“如何使用函数”:
var.get(a:number): any
下一个是var.get(a:string,b:number): any
下一个是var.get(): any
。
我知道 Roblox Lua (LuaU) 是可能的,并且它返回的页面就像我上面所做的那样。 我怎样才能做同样的事情? (请提供代码) 我确定它应该是一个函数,但它如何返回如何使用它的多种变体?
我尝试过:
local var={}
function var.get(a:number):any
-- some code here
end
function var.get():any
-- some code here
end
但是没有成功。
您想要做的事情的技术术语称为“函数重载”。目前在 Lua 或 Luau 中这是不可能的。早在 2020 年就曾提出过“引擎功能请求”,但并没有得到太多关注。 不能有多个具有相同名称和不同签名的函数。在您的示例中,将表
var
视为存储桶的集合。当您定义
get(a:number):any
函数时,您将其放入名为 get
的存储桶中。下次您尝试定义 get():any
时,您将清空名为 get
的存储桶并将其替换为新函数。每个存储桶中只能有一项内容,或者从技术上讲,您只能在表中的任何键上定义一个值。但是,如果您想实现类似函数重载,vanilla Lua 确实允许您使用任意数量的参数调用函数。这称为可变参数函数,它们非常有用,并且 Luau 也支持它们。
local var = {}
function var.get(...):any
local args = {...} -- store all the extra arguments in an array
--print(...) -- print out the arguments provided to get
-- figure out how people have called this function
if #args == 0 then -- called as get()
print("get() called with no arguments!")
else if #args == 1 then
print("get() called with one argument : ", args[1])
else
print("get() called with many arguments : ", ...)
end
return args
end
-- allows you to use it like...
var.get()
var.get("hello")
var.get("this", "is", "a", "test", 123, false)
就我个人而言,我不建议这样做。以任何您想要的方式调用函数的灵活性并不能证明完成这项工作所需的麻烦。简单地为不同的签名创建多个函数会更干净。
local var = {}
function var.get()
print("get()")
end
function var.getOne(n : number)
print("getOne", n)
end
function var.getTwo(n : number, s : string)
print("getTwo", n, s)
end
local function overloaded (signatures)
local concat = table.concat
-- Serialise signatures beforehand to compare them as strings at call time:
local serialised_signatures = {}
for signature, implementation in pairs (signatures) do
if type (signature) == 'number' then
-- syntactic sugar for an empty signature:
signature = ''
elseif type (signature) == 'table' then
-- long signatures:
signature = concat (signature, ', ')
end -- otherwise, it is a signature with one argument, which remains a string.
serialised_signatures [signature] = implementation
end
-- Get the serialised signature of a function call at runtime:
local function arg_types (...)
local types = {}
for i, arg in ipairs {...} do
types [i] = type (arg)
end
return concat (types, ', ') -- to make comparing easier.
end
return function (...)
local called_with_args = arg_types (...)
for signature, implementation in pairs (serialised_signatures) do
if called_with_args == signature then
return implementation (...)
end
end
end
end
local get = overloaded {
-- no arguments. [{}] or [''] index will have the same effect:
function ()
return 'If you want to get something, give something'
end,
-- one argument, number:
number = function (number)
return 'You have given the number ' .. number
end,
-- one argument, string, but passed as a list:
[{ 'string' }] = function (string)
return 'You have given the string "' .. string .. '"'
end,
-- several arguments:
[{ 'number', 'number' }] = function (no1, no2)
return 'You have given two numbers: ' .. no1 .. ' and ' .. no2
end
}
print ('get () = ' .. get ())
print ('get (42) = ' .. get (42))
print ("get 'fourty-two' = " .. get 'fourty-two')
print ('get (4, 2) = ' .. get (4, 2))