Могут ли 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)для вызова функции, хранящейся в этой переменной.

Другие вопросы по тегам