Here is a Julia implementation from this trait example in Rust By Example.
## Define the object
mutable struct Sheep
name::String
naked::Bool
end
Sheep(name) = Sheep(name, false)
is_naked(x::Sheep) = x.naked
name(x::Sheep) = x.name
noise(x::Sheep) = is_naked(x) ? "baaaah?" : "baaah!"
## For now, let's not define the custom version of `talk` and let it use
## the trait version.
# talk(x::Sheep) = println(name(x), " pauses briefly... ", noise(x))
function shear(x::Sheep)
if is_naked(x)
println(name(x), " is already naked...")
else
x.naked = true
println(name(x), " gets a haircut!")
end
end
## Define the trait
struct Animal end
struct NonAnimal end
isanimal(x::T) where T =
# The Animal trait has to have the following methods:
if hasmethod(name, Tuple{T}) &&
hasmethod(noise, Tuple{T})
Animal()
else
NonAnimal()
end
talk(x::T) where T = talk(isanimal(x), x)
talk(::Animal, x) = println(name(x), " says ", noise(x))
## Let's try it
dolly = Sheep("Dolly")
talk(dolly)
shear(dolly)
talk(dolly)
Right now, this uses dynamic dispatch because of hasmethod
. For a static version of hasmethod
, see Tricks.jl.
For more on Julia traits, see Lyndon White's blog post and the Julia manual here.