Consider the following code:
abstract type GameObject end
abstract type Weapon <: GameObject end
struct Sword <: Weapon
name::String
damage::Int32
end
struct Bow <:Weapon
name::String
damage::Int32
end
mutable struct Character
name::String
inventory :: Vector
function Character(name::String)
inventory = Vector{Weapon}()
new(name,inventory)
end
end
queen_svetlana = Character("Queen Svetlana")
push!(queen_svetlana.inventory,Sword("Sword",10), Bow("Bow",5))
As stated in Performance Tips, it’s better to use a container with a concrete type, so instead of Real
, you would use Float64
.
The problem is in a situation where you want to keep an assortment of Weapons
in one inventory, what is the efficient approach?
It seems kind of overkill to delcare a collection for each Weapon
sub type:
swords = Vector{Sword}()
bow = Vector{Bow}()
In Performance Tips, it also states:
If you cannot avoid containers with abstract value types, it is sometimes better to parametrize with
Any
to avoid runtime type checking.
The problem is, with Any
you could also add String
and Int
for a container meant only for Weapon
. You could work around the problem by writing your own push!()
function that takes a character and weapon, but nothing stops you from accessing the container directly.
I guess some context might be useful here:
-
Unlike a
Vector{Float64}
, we’re not doing any calculations with theVector{Weapons}
. We’re simply withdrawing a weapon to be used, and then putting it back afterwards. -
Using a
for
loop andisa()
we might filter certain weapons, if you want a brief summary of specific weapon types, andlength(inventory)
to get the number of weapons.
Does the Avoid containers with abstract type parameters tip depend on how the container will be used? Given the above situation of adding, removing and simply looping, would using Weapon
be okay?