Hello,
I’ve a problem with subtype, see the code:
abstract type LineAbstract end
mutable struct LineA <: LineAbstract
color::String
end
mutable struct LineB <: LineAbstract
length::Int
end
mutable struct Picture
lines::Vector{LineAbstract}
end
I’m putting here a conceptual problem of my real problem because it’s more easy to understand.
The class Picture
have lines, and they share some attributes in common, but the have it’s own.
In class Picture
I have all kinds of lines at only one attribute lines
, so I’ve this option above and the second one:
mutable struct Picture
lines::Vector{Union{LineA, LineB}}
end
Both are have bad performance, because first use abstract type and the second use union acoording with Performance Tips · The Julia Language.
I can’t split the property lines
in linesA
and linesB
.
How can I deal with it?
Sample of drawbacks:
la1 = LineA("blue");
la2 = LineA("yellow");
lb1 = LineB(10);
lb2 = LineB(50);
p = Picture([la1, la2, lb1, lb2]);
function paint(p)
for l in p.lines
paint(l)
end
end
paint(l::L) where L <: LineAbstract = println("Painting a line");
First Case Drawback Problem
Something similar happen with the second case.
> @code_warntype paint(p)
Variables
#self#::Core.Compiler.Const(paint, false)
p::Picture
@_3::Union{Nothing, Tuple{LineAbstract,Int64}}
l::LineAbstract
Body::Nothing
1 ─ %1 = Base.getproperty(p, :lines)::Array{LineAbstract,1}
│ (@_3 = Base.iterate(%1))
│ %3 = (@_3 === nothing)::Bool
│ %4 = Base.not_int(%3)::Bool
└── goto #4 if not %4
2 ┄ %6 = @_3::Tuple{LineAbstract,Int64}::Tuple{LineAbstract,Int64}
│ (l = Core.getfield(%6, 1))
│ %8 = Core.getfield(%6, 2)::Int64
│ Main.paint(l)
│ (@_3 = Base.iterate(%1, %8))
│ %11 = (@_3 === nothing)::Bool
│ %12 = Base.not_int(%11)::Bool
└── goto #4 if not %12
3 ─ goto #2
4 ┄ return
Thank you a lot.