Julia:循环引用

问题描述 投票:0回答:3

如何解决这个问题?

mutable struct Parent
    name::String
    children::Vector{Child}

    function Parent(name)
        return new(name)

    end

end

mutable struct Child
    name::String
    parent::Parent

    function Child(name)
        return new(name)

    end

end

parent = Parent("father")
child = Child("son")

产生错误

LoadError:UndefVarError:未定义子项

有什么办法可以处理这种情况吗?

julia
3个回答
8
投票

据我所知,目前处理此问题的唯一方法是通过参数类型(我知道它并不完美)。这是一个额外限制参数的示例,以便您几乎得到您想要的:

abstract type AbstractChild end

mutable struct Parent{T<:AbstractChild}
    name::String
    children::Vector{T}
    function Parent{T}(name) where {T<:AbstractChild}
        return new{T}(name)
    end

end

mutable struct Child <: AbstractChild
    name::String
    parent::Parent

    function Child(name)
        return new(name)
    end
end

Parent(name) = Parent{Child}(name)

parent = Parent("father")
child = Child("son")

0
投票

只是为了添加@Bogumił Kamiński 的答案,抽象类型 AbstractChild end 会为 Julia 创建一个节点,以便在程序运行时进行遍历。


0
投票

利用抽象类型似乎是循环情况的预期用途。

abstract type AbstractChild end

mutable struct Parent <: AbstractChild
    name::String
    children::Vector{AbstractChild}
    
    Parent(name) = new(name, Vector{AbstractChild}())
end

mutable struct Child <: AbstractChild
    name::String
    parents::Tuple{AbstractChild, AbstractChild}

    Child(name) = new(name)
end

link(parent1::Parent, parent2::Parent, child::Child) = (
    push!(parent1.children, child);
    push!(parent2.children, child);
    child.parents = (parent1, parent2)
)

father = Parent("father")
mother = Parent("mother")
child = Child("son")

link(father, mother, child)

运行代码并检查结构会产生以下输出(Juila 1.9.4):

julia> father
Parent("father", AbstractChild[Child("son", (Parent(#= circular reference @-4 =#), Parent("mother", AbstractChild[Child(#= circular reference @-4 =#)])))])

julia> mother
Parent("mother", AbstractChild[Child("son", (Parent("father", AbstractChild[Child(#= circular reference @-4 =#)]), Parent(#= circular reference @-4 =#)))])

julia> child
Child("son", (Parent("father", AbstractChild[Child(#= circular reference @-4 =#)]), Parent("mother", AbstractChild[Child(#= circular reference @-4 =#)])))

根据[link],

#= circular reference @-4 =#
是一个好兆头,表明我们已经正确设置了双向参考。

© www.soinside.com 2019 - 2024. All rights reserved.