godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.87k stars 21.01k forks source link

Dictionary Lookups with float/int confusion. #82575

Open sdfgeoff opened 1 year ago

sdfgeoff commented 1 year ago

Godot version

4.1.1 stab;e

System information

arch

Issue description

In gdscript, a float can be compared to an int:

2.0 == 2  # true
2.1 == 2 # false

You can also use floats an ints as dictionary keys:

var d = {
    2: 'a',
}
d[2]  # 'a'

But dictionary keys don't do equality, so:

var d = {
    2: 'a',
}
d[2]  # 'a'
d[2.0]  # IndexError

image

I don't know that this needs to be fixed as it is (in hindsight) obvious that this is how it would work, but it did leave me on a merry bughunt, and printing the values/comparing equality didn't reveal the issue.

Steps to reproduce

func _init():
    print(2 == 2.0)
    var data = {
        2: 'a'
    }
    print(data[2])
    print(data[2.0])

Minimal reproduction project

Code example above

dalexeev commented 1 year ago

You can use the is_same() function instead of the == operator for a stricter and safer comparison. I'm not sure if we should change the behavior of dictionaries. On the one hand, this was done for String vs StringName. On the other hand, in addition to int vs float, we have many other similar types like Vector2i vs Vector2, and what’s even worse, PackedInt64Array vs PackedFloat64Array, Array[int] vs Array[float] (they can also be dictionary keys). And dictionaries are not the only place where comparisons are more strict, for example match also compares values differently than the == operator.