Curiously didn’t find anything on this, even after some decent amount of googling…
I have a structure, and then I have a version of it with some additional info. Can I make the latter inherit from the former? Naively, I thought this would work:
struct MyStruct
a::Int64
end
struct ExpandedMyStruct <: MyStruct
a::Int64 # Tried both with and without this line
b::Int64
end
but this yields a invalid subtyping in definition of ExpandedMyStruct
error.
The reason I want to do this is that I have a function (that works on MyStruct
), e.g.
function f(ms::MyStruct)
println(ms.a)
end
f(MyStruct(2))
and I want to make this work on ExpandedMyStruct
by default (without having to declare it as function f(ms::Union{MyStruct,ExpandedMyStruct)
. Does what I am trying to do make sense?
How about this?
julia> abstract type MyAbstract end
julia> struct MyStruct <: MyAbstract
a::Int
end
julia> struct AlsoMyStruct <: MyAbstract
a::Int
end
julia> f(x::MyAbstract) = x.a
f (generic function with 1 method)
julia> f(MyStruct(3))
3
julia> f(AlsoMyStruct(3))
3
1 Like
Looks good. Is there a reason for this, seemingly a bit convoluted, way of doing it? Tried to find stuff about this in the Julia doc, but did;t find anything.
Yes, it is discussed in the manual Types · The Julia Language
One particularly distinctive feature of Julia’s type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes. While this might at first seem unduly restrictive, it has many beneficial consequences with surprisingly few drawbacks. It turns out that being able to inherit behavior is much more important than being able to inherit structure, and inheriting both causes significant difficulties in traditional object-oriented languages.
2 Likes