Okay so I wanted to make some quick ways to get data from an array of custom types, but I need some advice to avoid ambiguous method errors.
So I have code that does something like this (note that you need to define at least two methods , so for two different custom element types):
struct MyStruct{T}
value::T
end
function Base.getproperty(vector::Vector{<:MyStruct}, s::Symbol)
if s == :value
return [x.value for x in vector]
elseif s in fieldnames(Vector)
return getfield(vector, s)
else
error("cannot retrieve $s from Vector{<:MyStruct}")
end
end
struct MyOtherStruct{T}
another_value::T
end
function Base.getproperty(vector::Vector{<:MyOtherStruct}, s::Symbol)
if s == :another_value
return [x.another_value for x in vector]
elseif s in fieldnames(Vector)
return getfield(vector, s)
else
error("cannot retrieve $s from Vector{<:MyOtherStruct}")
end
end
I just want this for some syntactic sugar, like:
julia> [MyStruct(5), MyStruct(7)].value
2-element Vector{Int64}:
5
7
I might also want to define this for SubArray
and in general just AbstractArray
, but let’s just work with Vector
as an example for now.
So everything was working fine. But then I got an error with AlgebraOfGraphics v0.10.2, which called into Dictionaries v0.4.5, basically doing this:
using Dictionaries
p = pairs(NamedTuple())
dictionary(p)
This calles into sizehint!
with an empty vector, as such:
empty_vector = Vector{Union{}}()
sizehint!(empty_vector , 8)
And now I get ambiguous errors, because sizehint!
calls empty_vector.ref
. So that’s the minimum working example, just doing getproperty(Vector{Union{}}(), :ref)
:
ERROR: MethodError: getproperty(::Vector{Union{}}, ::Symbol) is ambiguous.
Candidates:
getproperty(vector::Vector{<:MyOtherStruct}, s::Symbol)
@ Main Untitled-1:19
getproperty(vector::Vector{<:MyStruct}, s::Symbol)
@ Main Untitled-1:10
Possible fix, define
getproperty(::Vector{Union{}}, ::Symbol)
I don’t want to define that method getproperty(::Vector{Union{}}, ::Symbol)
in my packages, that would clearly be type piracy.
So I’m wondering if my code is wrong. Or should I just not want to do this? Or should I open an issue on the Julia language github to solve this method ambiguity explicitly?