Just a curiosity: is there any particular reason for the slightly odd choice of access functions for named tuples? I would expect to have hasfield and getfield, or alternatively haskey and getkey, but I see a mixture of them instead.
julia> a, c = 1, 2;
julia> nt = (;a, c)
(a = 1, c = 2)
julia> haskey(nt, :a)
true
julia> haskey(nt, :c)
true
julia> haskey(nt, :b)
false
julia> T = typeof(nt)
@NamedTuple{a::Int64, c::Int64}
julia> hasfield(T, :a)
true
julia> hasfield(T, :c)
true
julia> hasfield(T, :b)
false
NamedTuples support retrieving valus via getproperty/getfield and getindex.
See
nt = (; a=1, b=2)
@assert nt.a == nt[:a]
getindex/setindex for types that have integer keys (tuples and arrays).
getproperty/setproperty for types with Symbol properties that are known at compile time (structs and named tuples). These can be overloaded for custom types to provide special handling of the dot access to properties.
getfield/setfield for the same as above, but should cannot be overloaded so you can still access the raw fields.
getkey/setkey for Dictionary like types whose keys are set dynamically at runtime.
Edit: fix to reflect that get/set field can’t be overloaded. Thanks @sgaure !
These are builtins, not generics, and can’t be overloaded.
julia> Base.getfield(a::NamedTuple, s::Symbol) = 1
ERROR: cannot add methods to builtin function `getfield`
Thank you all @_bernhard, @mrufsvold, and @sgaure. @mrufsvold , your summary recap is really useful.
I know recognize that my confusion was due to erroneously thinking that hasfield, similarly to hasproperty, could be applied to instances. Instead, it has to be used on types. My bad…