Могут ли Godot и GDScript хранить функции в переменных?
Я смущен частью Документов Годо для языка GDScript. Кажется, противоречит самому себе. Примерно на полпути вниз по странице, в разделе "Ссылки на функции", говорится, что вы не можете хранить функции в переменных, а затем, кажется, немедленно противоречит самому себе.
Можно ли хранить функции Годо в переменных или нет?
Функции ссылок
В отличие от Python, функции не являются объектами первого класса в GDScript. Это означает, что они не могут быть сохранены в переменных, переданы в качестве аргумента другой функции или возвращены из других функций. Это из соображений производительности.
Чтобы ссылаться на функцию по имени во время выполнения (например, чтобы сохранить ее в переменной или передать ее другой функции в качестве аргумента), необходимо использовать помощники call или funcref:
2 ответа
Функции 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_instance.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, см. документацию по ссылкам на функции (и следующий раздел о лямбда-выражениях).
В основном вы можете объявить переменную, используя
var f = func foo(x):
<function body>
а потомf.call(x)
для вызова функции, хранящейся в этой переменной.