drose
drose

Reputation: 43

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.

Upvotes: 4

Views: 972

Answers (1)

Przemyslaw Szufel
Przemyslaw Szufel

Reputation: 42224

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))

Upvotes: 2

Related Questions