Say I have two types that are both subtypes of an abstract type
abstract A
type B <: A
x
y
z
end
type C <: A
x
y
z
w
end
is there any way of creating C
without having to basically copy/paste B
and add the extra parameters? The main issue is that B
and C
are really close and I would prefer as little code duplication as possible. I know the manual says that concrete types can't subtype each other:
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.
Is there any way around this?
In these cases I usually prefer to compose my types.
Here is an example of what I mean:
abstract A
type B <: A
x
y
z
end
type C <: A
b::B
w
end
Notice how C
is still a subtype of A
, but contains an instance of B
as a field.
It is true that you can no longer access c.x
, but rather you have to do c.b.x
. There is a simple way around this.
Suppose you have a function
function my_func(a::A)
# do something with a.x, a.y, a.z
end
If my_func
is supposed to work with any subtype of A
, it can only access fields that are common across all subtypes of A
. In this case that is x
, y
, and z
.
Knowing that, I would also define a specialized version of that method to dispatch on instances of C
as follows:
my_func(c::C) = my_func(c.b)
This is a bit more verbose, but you can easily wrap all these functions in a metaprogramming for loop that uses @eval
and generate them all at once. See docs for more info
I would do
type XYZ
x
y
z
end
type B <: A
xyz::XYZ
end
type C <: A
xyz::XYZ
w
end
Of course, for performance reason I normally use immutable
as well as annotate as much types as possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With