我对 GDScript 语言 的部分 Godot 文档感到困惑。大约在页面的中间,在“引用函数”部分,它说你不能将函数存储在变量中,然后似乎立即自相矛盾。
Godot 函数可以存储在变量中吗?
参考函数
与 Python 相反,函数在 GDScript 中不是第一类对象。 这意味着它们不能存储在变量中、作为参数传递给另一个函数或从其他函数返回。这是出于性能原因。
要在运行时按名称引用函数,(例如,将其存储在变量中,或将其作为参数传递给另一个函数)必须使用 call 或 funcref 帮助器:
Godot v4.0 添加了由
Callable
对象支持的一流函数和 lambda。
阅读过去的发布博客以获取更多信息。
现在,您可以按名称传递函数:
func callback(p_arg: String) -> void:
print("Argument: ", p_arg)
func accept(p_callback) -> void:
p_callback.call("accepted")
func _ready() -> void:
accept(callback) # Prints "Argument: accepted"
并定义 lambda/闭包:
var lambda = func a_debug_label(p_arg: String) -> void:
print("Argument: ", p_arg)
accept(lambda) # Prints: "Argument: accepted"
accept(func(p_arg): print(p_arg)) # Prints: "accepted"
Callables
替换 funcrefs:
var callable = Callable(my_obj, "some_func_name")
callable.call()
请注意,可调用对象是包装目标对象和函数名称的对象。可调用本身不是函数。您必须致电
some_callable.call()
。最后,lambda 的名称不可访问。它仅用于调试目的。
GDScript 函数不像 Python 中那样是对象。因此,您不能直接引用函数。
但是,您可以使用其关联的实例按名称间接引用它们。
例如具有以下功能:
func hello():
print('Hello')
您可以通过名称调用实例上的函数:
call('hello') # prints 'Hello'
您可以使用
funcref()
存储实例和函数名称:
var ref = funcref(hello_object_instance, 'hello')
ref.call_func() # prints 'Hello'
takes_func_ref_to_call_later(ref) # later, prints 'Hello'
FuncRef.call_func()
与 Object.call()
做同样的事情,只是将其包装在一个对象中。
因此,如
Object.connect()
和朋友所示,回调函数的常见模式是:
func deferred_finish(param1, param2, callback_obj, callback_func):
# ... do something
callback_ref = funcref(callback_obj, callback_func)
func _process(delta):
if _finished:
callback_ref.call_func()
func _enter_tree():
deferred_finish('hello', 'world', self, 'finished_callback')
我希望这有帮助。如果您需要任何说明,请告诉我。
据我所知,它在 3.x 中不可用,但它是 Godot 4.0 中的一个功能,请参阅有关 引用函数 的文档(以及以下有关 lambda 的部分
基本上你可以使用声明变量
var f = func foo(x):
<function body>
然后
f.call(x)
调用存储在该变量中的函数。