Это форма полиморфизма через композицию (а не наследование).
Скажем, у одного есть тип-обертка, оборачивающий некоторый экземпляр конкретного подтипа AbstractT
, где сама обертка должна быть подтипом.AbstractT
(не всегда верно, но в целом).
Чтобы добавить все методы, которые требуются для такого подтипа AbstractT
, мы хотим делегировать некоторые иливсе эти методы для обернутого объекта.Мы делаем это через метапрограммирование.Есть несколько вариантов того, как это сделать.Но в целом, абстрагироваться сложно, поэтому люди часто пишут свои собственные.
Скажи, что все подтипы AbstractT
должны реализовывать 1arg length
, size
и mean
struct WrappedT{T<:AbstractT} <: AbstractT
backing ::T
...
end
for fun in (:(Base.length), :(Base.size), :(Statistics.mean))
@eval ($fun)(x::WrappedT, args...) = ($fun(x.backing, args...))
end
Как правило, вы не будете делегировать все методы, поскольку некоторые из них вы захотите сделать по-другому, в этом и заключается смысл создания нового типа.