It seems to me that a hash is created when the object is created, and it is never updated after. I checked and creating the object directly with field age of value 30 leads to a different hash:
This behavior seems optimal for immutable types, but not for mutable ones.
You should probably define your own hash function, or use something like AutoHashEquals.jl which has a macro that takes the struct definition and automatically defines hash and isequal for it.
ABOUT QUESTION 2:
Yes, Set probably uses hash (or isequal) and you should not use mutable structs as keys of hashing containers (in the Set the element is both value and key) unless you are sure they will not change, or is prepared to deal with them changing.
In the case you change them, they will probably keep stored by their old hash value, and if you search for them with an object created with the new values, then you will not find the stored objects. It can become impossible to find them by their old value also, because they are not only searched by hash, but compared by value before being returned.
Right, hash by default just uses the object ID. That’s consistent with the default behavior of == which falls back to === and thus also uses the object ID. The important invariant is that x == y implies hash(x) == hash(y), and that invariant holds here.
(a) use AutoHashEquals.jl
(b) Best to review your own code and make certain that you define the custom equals in terms of the custom hash for each of your own types.
(c) Otherwise, the only way to be certain would be to test every possible value of each type.