-
-
Notifications
You must be signed in to change notification settings - Fork 22k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dictionaries are compared by reference with ==
, unlike Arrays which are compared by value
#27615
Comments
This is intended. You look if the references of two dictionaries are the same, so creating two with the same values won't work. |
I mean, why do dicts comparison treat it via ref to the same object whereas Arrays are based on values. |
@CodeDarigan arrays used to be compared by ref too in the past. Then there was requests to make arrays compared by value and now they are by value ¯\_(ツ)_/¯ |
This can be worked around thanks to the var x = {0: 10}
var y = {0: 10}
print(x.hash() == y.hash()) # Outputs `true` |
See also #29222. |
Actually no, this doesn't quite work, cause the order matters since some other ppl complained that there wasn't order preservation with dicts. So we get something like: var d1 := {x = 0, y = 1}
var d2 := {y = 1, x = 0}
print(d1.hash() == d2.hash()) # False Is there a way to preserve ordering and have the hashes be the same? I would think not, but honestly... I prefer unordered dicts because of this comparison issue. Unordered dicts are the default in many languages. |
@razcore-art Dictionaries are ordered since Godot 3.0, but there's no way to opt out of that behvior. |
I just wanted to chime in that this recently bit me, as the order matters and so for complicated Dictionaries comparison via hash() is useless if just one element is out of order. Tracking how many times I have stumbled upon this issue. Hopefully one day I will remember this. Different ways i have encountered this: "==", "in", "has()", "get()". I have been here: 9 times, because of run ins with this bug in various ways. The reason that you can not trust hash() is because if the dictionaries have the same keys and the same values, but the order of the keys is different then the hash() will also be different. This really makes zero sense, especially since by definition dictionaries are not ordered. |
See godotengine#27615. (cherry picked from commit 77b8926)
I think dictionarys should be compared by value. It's just really confusing if you didn't hear before that they are compared by ref. |
Despite the fact I disagreed with all this by-value stuff that happened to arrays and dictionaries, and the fact dictionaries (famously being an unordered data structure) have been given ordered behavior which now causes unexpected problems with Comparing by value can be done with some code, comparing by ref cannot. So some people are currently stuck because they need reference comparison: #33627 Now, not saying we shouldn't do this (Python does it, so... it's possible). Just wanted to warn about the issues of such a decision, and at least we should expose a way to compare by ref. |
I came across this looking for a way to compare two dictionaries, so allow me to give my two cents. Regardless of the behaviour of GDScript could take the Java approach, and have IMO, having an inconsistent Sorry if any of this came up as anything other than constructive criticism! GDScript is a very nice language and I only want to see it become even better! :) |
==
, unlike Arrays
==
, unlike Arrays==
, unlike Arrays which are compared by value
I think it was a mistake to have changed the behaviour from refs to values: 1. inconsistency (with dictionaries as well as objects) and 2. more fatally, leaving no way to check for identity. So, agree with @setzer22 that upon some bigger version change, this should be changed, too. And would really like some hot-fix method to test for indentity of arrays if possible - then many can do simple workarounds without having to use heavier objects (or dictionaries) in custom databases and such where simple arrays would be just fine. (Also, compare storing arrays vs. objects with repeating keys.) |
@takaturre Changing equality behavior is a breaking change. We can't merge something that changes the existing behavior in 3.2.x, as we want people to be able to upgrade projects between patch releases as smoothly as possible (and avoid any regressions). |
@Calinou Yes, I agree 100%. That's why gave my vote for doing it in the long run (eg. v4.0, especially if it includes changes like Spatial --> Node3D), and just making a "hot-fix method" now (if that's possible easily) to enable checking whether two arrays are identical (the very same array reference) or not. For example,
|
Just wanted to note something that hasn't been mentioned: most languages distinguish between identity comparison and equality comparison explicitly, plus in OO languages you also want a type comparison.
Gdscript is less clear:
I do like python's setup, as using So I would vote for switching to the python way, but in the short term IMHO, the least disruptive way seems to be to add an |
See godotengine#27615. (cherry picked from commit 77b8926)
Fixed by #35816. |
Godot 3.1
In Python (for example), if you were to compare Dictionaries they would evaluate to true as long as key-value pairs were the same. In GDScript, Dictionary comparison is based on a reference to the same Dictionary Object.
Is this the intended behaviour?
The text was updated successfully, but these errors were encountered: