godot
godot copied to clipboard
GDScript: Unexpected behavior of `match` on float variable with integral constants
Godot version
4.0 stable
System information
macOS 13.2.1
Issue description
When performing a match on a float variable, the match will fail if the match arms are written as integral constants. That is, if the variable contains the value 5.0, a match arm of 5 will fail to match. This is non-obvious behavior for users coming from most other programming languages.
Steps to reproduce
See minimal GDScript snippet
Minimal reproduction project
func test():
var a: float = 20.0
match a:
20:
print("PASS")
_:
print("FAIL")
This is intentional. match is more strict than ==. In 3.x the behavior is the same.
So match's documentation needs to be improved:
https://github.com/godotengine/godot-docs/blob/b8eb2d2a6ea4f3abb29ba79f6a99092abdfad95e/tutorials/scripting/gdscript/gdscript_basics.rst#match
It doesn't tell how exactly comparisons are done (e.g. if they're type-strict). Besides that I'm not sure if it's up to date (if / what has changed since it was written).
Also it says:
It's the equivalent of the
switchstatement found in many other languages
which may lead to confusion like in here (as these are not necessarily equivalent, rather similar).
It seems that, with static typing information, there should at least be a warning for impossible match arms based on types.
Hi, I noticed the same thing. Match statement and if/elif work differently with numbers, see code below. I think it is necessary to add an explanation to the documentation on match, if/elif and JSON (All number parsed from JSON became float).
var f : float = 8 var i : int = 2 var dictionary = {"some": 5, "random": i, "numbers" : f} var array = [5, i, f]
for n in array.size(): print("> for i in array: ", array[n], " type of: ", typeof(array[n])) if array[n] == 5: print("Is equal to 5") elif array[n] == 2: print("Is equal to 2") elif array[n] == 8: # <-- here we compare float 8 to 8, and it is ok print("Is equal to 8") else: print("The numbers are not equal!")
for n in dictionary: print("> For n dictionary: ", dictionary[n], " type of: ", typeof(dictionary[n])) match dictionary[n]: 5: print("> Wow it's matched to 5") 2: print("> Wow it's matched to 2") 8: print("> Wow it's matched to 8") # <-- here the same comparison will fail _: print("No match!") ` Output will be:
for i in array: 5 type of: 2 Is equal to 5 for i in array: 2 type of: 2 Is equal to 2 for i in array: 8 type of: 3 Is equal to 8 For n dictionary: 5 type of: 2 Wow it's matched to 5 For n dictionary: 2 type of: 2 Wow it's matched to 2 For n dictionary: 8 type of: 3 No match! `