Godot Version
v4.6.2.stable.official [71f334935]
Question
I’ve created a class that I’d like to use as a key in dictionary. I want to use it as a lookup for hotkey keypresses. I can’t find any info on whether there needs to be any special handling for it - I know in languages like C++, you need to define a hash function for data structures used as keys.
Can I assume Godot will compare two keys based on their content, or do I have to do something extra like implementing things like hash and equals methods?
Eg, for this class:
@tool
extends Resource
class_name KeymapKeypress
@export var keycode:Key = KEY_NONE
@export var shift:bool = false
@export var ctrl:bool = false
@export var alt:bool = false
@export var meta:bool = false
Will this work (ie, print 6):
var map:Dictionary[KeymapKeypress, int]
var key1 = KeymapKeypress.new()
key1.keycode = KEY_A
var key2 = KeymapKeypress.new()
key2.keycode = KEY_A
map[key1] = 5
map[key2] = 6
print(map[key1])
Yes that works. Your example will print 5 though.
Theoretically Godot can hash by the memory address of any given object, I don’t think it is serializing the object as your two keys would produce the same serialized data, and that’s not what I would want from using my objects as keys anyways.
You can use objects as keys without any problems. Note that it’s not object’s value (data) that’s used as a key/hash but the reference itself, which will always be unique. Internally, Godot might in fact use pointers (i.e. object’s memory addresses) for that.
I don’t want to compare by the object reference. I want to be able to construct a key and then check if the dictionary already has that. Other languages like Python and Java let you do this by allowing you to define equals() and hashcode() methds that are part of their base object.
Do I have to create a hash manually and then use that as my key?
You want to hash by value?
Yes. Like in my example, I want to check if a user’s input keypress is already in my hash table. I could create string based on the input and then use that as my key, but it would be more elegant to use a custom object as my key (that I could look up by value). I’m kinda of surprised this isn’t in GDScript already.
In that case, calculate the key from the object data in whatever way suits your use case, and just use that. You can always implement the hashing function as a part of that object’s class.