Function references can be tricky.
What's the difference between:
func _ready() -> void:
launch_rockets()
func launch_rockets() -> void:
print("Launching rockets!")
func _ready() -> void:
launch_rockets
func launch_rockets() -> void:
print("Launching rockets!")
In the first example, launch_rockets()
is called, and the function executes. In the second example, launch_rockets
refers to the function, and it's not called. It's just the function's name.
Remember, a function is like a recipe in a cooking book. For example, if the book has a recipe for a chocolate cake, I could tell you to "make the cake". That's like calling the function. But if I say "chocolate cake", that's like just giving you the recipe's name.
The ()
at the end of a function name is a shortcut for "call this function". It is actually a shortcut for .call()
. launch_rockets()
is the same as launch_rockets.call()
.
launch_rockets()
means "execute the function launch_rockets
"
launch_rockets
means "the function launch_rockets
"
Do you remember how you used to reduce a math equation?
y = (2 + 3) * (5 * (1+1) )
y = 5 * (5 * 2)
y = 5 * 10
y = 50
You first resolve internal parenthesis. Programming languages do the same with functions.
In the example below, five()
and three()
are functions that return numbers. When you call them, you get the number they return. They get evaluated by Godot before print()
is called:
func five() -> int:
return 5
func three() -> int:
return 3
func _ready() -> void:
print(five() + three())
Note that print(five + three)
wouldn't work, as you can't add function references together.
Where do you use function references? One everyday use is in connect()
.
When connecting a signal to a function, you reference the function's name. For example:
tween.finished.connect(launch_rockets)
This tells the tween
to call launch_rockets
when it's finished. Using the cake example again, it'd be like saying, "When the tween finishes, make the recipe called chocolate cake
".
In contrast, if you use parentheses, you're calling the function, and that's probably not what you want:
tween.finished.connect(launch_rockets())
Because launch_rockets()
finishes first and returns void
, the expression becomes:
tween.finished.connect(null)
In plain language, that'd be like saying: "Make the cake. When the tween finishes, cake", which doesn't make sense since "cake" is not an action.
Sometimes, you want to use a function reference, but you want to give it arguments.
For example, the Button
's pressed
signal doesn't give you any arguments. But what if you want to pass the button's name to the function?
One way is to use lamba functions. They're like mini-functions that you can define on the spot. For example:
button.pressed.connect(func() -> void:
launch_rockets(button.name)
)
Another is to use the bind()
function. bind creates a new function that calls the original function with the arguments you provided:
button.pressed.connect(launch_rockets.bind(button.name))
In this case, bind
creates a new function that calls launch_rockets
with the button.name
argument. It's similar to using the lambda function, but it's more concise.See Also
Related terms in the Glossary