【问题标题】:Declare type of struct field to be the same type as the struct itself in Julia将结构字段的类型声明为与 Julia 中的结构本身相同的类型
【发布时间】:2021-02-22 22:34:44
【问题描述】:

如果我在 Julia 中定义一个结构,是否可以将其中一个字段的类型声明为与结构本身的类型相同?例如,我想定义一个结构 NodeStruct 有两个字段,datanext 其中data 是一些标准类型(例如AbstractFloat)和nextNodeStruct 类型或nothing .考虑这个给出错误LoadError: UndefVarError: NodeStruct not defined的示例代码。

import Base.@kwdef

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

有可能以某种方式做到这一点吗?我希望能够以参数方式执行此操作,因为performance tips 建议这样做,并且计算时间对我来说非常重要。我在typesconstructors 的文档中找不到任何解决此问题的信息。

【问题讨论】:

    标签: performance struct types julia field


    【解决方案1】:

    既然你知道你的结构元素是一个具体的类型,这将是:

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

    现在你只需使用它

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

    如果您需要更抽象的结构,您可以这样做:

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

    为这个抽象结构创建根时,您需要提供类型:

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

    但是对于叶子,它会起作用:

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

    【讨论】:

    • 感谢您的回复。但是,以这种方式定义结构似乎提出了另一个问题。如果我用您编写的结构定义替换我的结构定义(然后重新启动 Julia),然后运行代码,它会第一次运行,但随后所有连续尝试运行定义此结构的代码都会给出LoadError: invalid redefinition of constant NodeStruct。正常的结构定义通常不会发生这种情况。为了清楚起见,我知道如果您在不重新启动 Julia 的情况下更改结构定义也会发生此错误,但在这种情况下,这不是问题。
    • "运行代码的所有连续尝试" - 您只能定义一次 struct。以后的定义必须使用不同的名称,否则您需要重新启动 Julia。
    • 对不起,请允许我详细说明一下。通常,如果我在文件中定义一个结构,例如MyStruct.jl 然后我创建另一个以include("MyStruct.jl") 开头的文件 NewFile.jl,然后我通常可以在不重新启动 Julia 的情况下多次运行 NewFile.jl。但是,如果我尝试使用例如在 NodeStruct 中声明一个字段next ::NodeStructnext ::Union{NodeStruct, Nothing},那么我只能运行一次 NewFile.jl 而无需重新启动 Julia。我想这不是预期的行为?谢谢。
    • 在我的机器(Julia 1.6.0 RC1)上,当我不更改定义时,我可以运行多次。这似乎是一个单独问题的主题。
    • 作为记录,我使用 Julia 1.3.1 时它不起作用,我刚刚更新到 Julia 1.6.0 RC1,现在它可以工作了,这样就解决了这个问题。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    相关资源
    最近更新 更多