Copying struct fields to another struct

For example I have an -

abstract type A

abstract type B <: A

struct C <: B

Now, I want another struct D which has all fields of C but is a subtype of A i.e,

struct D <: A
C fields

Is there a way to do this, without manually copy pasting the contents ?

1 Like

No, at least not without macros. Copy and paste is honorable.


Is Mixers.jl what you want? And what about Classes.jl?

1 Like

Mixers.jl will work, but it ends up constructing a whole bunch of macros. I managed to build a single macro that does what I need it to do, and handles parametric types.

function get_type_expression(X::Union{Symbol,DataType})
    if X isa Symbol
        return X
    elseif X isa DataType
        Params = X.parameters
        if isempty(Params)
            return Symbol(
            return Expr(:curly, Symbol(, Params...)

macro inherit_fields(AssetTypeExp::Expr)
    BaseAssetType = Core.eval(@__MODULE__, AssetTypeExp.args[1])
    TypeSymbols   = AssetTypeExp.args[2:end]
    AssetType     = BaseAssetType{TypeSymbols...}

    ex = Expr(:block)
    for fName in fieldnames(AssetType)
        fType = fieldtype(AssetType, fName)
        fTypeParsed = get_type_expression(fType)
        push!(ex.args, :( $fName :: $fTypeParsed ) )

    return esc(ex)

You can then use this macro pretty intuitively as follows:

mutable struct MyOldType{T}
    Name :: Symbol
    A :: T
    B :: T
    V :: Vector{T}

mutable struct MyNewType{T}
    C :: T

As you can see, it’s all done in one neat step without building a whole bunch of specific macros as you would do in Mixers.jl. You can even modify this by adding a second argument that lists fields you want to leave out of the inheritance and filtering those out of the for loop (keep in mind that the field array will be an expression so you will have to evaluate it to get an array of Symbols).

1 Like