Basic
Here's an example of single-argument interface using animals, and the implementation of a duck.
Definition
First we define the interface methods, and a list of mandatory and optional properties of the interface, with conditions, using the @interface macro.
The @interface macro takes three arguments:
- The name of the interface, which should usully end with "Interface"
- The
mandatoryandoptionalcomponents of the interface written as aNamedTuple, with functions or tuple of functions that test them. - The interface docstring (the interface is represented as a type)
module Animals
using Interfaces
abstract type Animal end
function age end
function walk end
function talk end
function dig end
components = (
mandatory = (
age = (
"all animals have a `Real` age" => x -> age(x) isa Real,
"all animals have an age larger than zero" => x -> age(x) >= 0,
),
),
optional = (
walk = "this animal can walk" => x -> walk(x) isa String,
talk = "this animal can talk" => x -> talk(x) isa Symbol,
dig = "this animal can dig" => x -> dig(x) isa String,
)
)
description = """
Defines a generic interface for animals to do the things they do best.
"""
@interface AnimalInterface Animal components description
end;Implementation
using Interfaces, TestNow we implement the AnimalInterface, for a Duck.
struct Duck <: Animals.Animal
age::Int
end
Animals.age(duck::Duck) = duck.age
Animals.walk(::Duck) = "waddle"
Animals.talk(::Duck) = :quackWe then test that the interface is correctly implemented
ducks = [Duck(1), Duck(2)]
Interfaces.test(Animals.AnimalInterface, Duck, ducks)trueAs well as two optional methods
Interfaces.test(Animals.AnimalInterface{(:walk,:talk)}, Duck, ducks)trueFinally we declare it, so that the information can be used in static dispatch.
The @implements macro takes two arguments.
- The interface type, with a tuple of optional components in its first type parameter.
- The type for which the interface is implemented.
@implements Animals.AnimalInterface{(:walk,:talk)} Duck [Duck(1), Duck(2)]Now let's see what happens when the interface is not correctly implemented.
struct Chicken <: Animals.Animal endAs expected, the tests fail
chickens = [Chicken()]
try
Interfaces.test(Animals.AnimalInterface, Chicken, chickens)
catch e
print(e)
end
@test Interfaces.test(Duck) == true # Test all implemented interfaces for Duck
@test Interfaces.test(Animals.AnimalInterface) == true # Test all implemented types for AnimalInterface
@test Interfaces.test_objects(Animals.AnimalInterface) == Dict(Duck => ducks)Test PassedThis page was generated using Literate.jl.