Declare type of struct field to be the same type as the struct itself in Julia

If I define a struct in Julia, is it possible to declare the type of one of its fields to be of the same type as the struct itself? For example, I want to define a struct NodeStruct with two fields, data and next where data is some standard type (e.g. AbstractFloat) and next is NodeStruct type or nothing. Consider this example code which gives an error LoadError: UndefVarError: NodeStruct not defined.

import Base.@kwdef

@kwdef mutable struct NodeStruct{A<:AbstractFloat, B<:Union{NodeStruct, Nothing}}
    data ::A
    next ::B
end

Is it possible to do this somehow? I would like to be able to do this parametrically as the performance tips suggest this and computation time is very important to me. I could not find any information in the documentation on types or constructors that resolves this issue.

Thank you for reading and I would appreciate any advice that you might have.

1 answer

  • answered 2021-02-22 22:49 Przemyslaw Szufel

    Since you know that elements of your structure a concrete type this just will be:

    @kwdef mutable struct NodeStruct{A<:AbstractFloat}
        data ::A
        next ::Union{NodeStruct, Nothing}
    end
    

    And now you just use it

    julia> NodeStruct(3.5, nothing)
    NodeStruct{Float64}(3.5, nothing)
    

    If you need slightly more abstract structure you can do:

    abstract type AbstractNS end
    
    @kwdef mutable struct NodeStruct2{A<:AbstractFloat, B<:AbstractNS} <: AbstractNS
        data ::A
        next ::Union{Nothing, B}
    end
    

    When creating the root for this abstract structure you need to provide the type:

    julia> root = NodeStruct2{Float64, NodeStruct2}(3.5, nothing)
    NodeStruct2{Float64, NodeStruct2}(3.5, nothing)
    

    However for leaves it will just work:

    julia> leaf = NodeStruct2(5.6, root)
    NodeStruct2{Float64, NodeStruct2{Float64, NodeStruct2}}(5.6, NodeStruct2{Float64, NodeStruct2}(3.5, nothing))