如何定义两个相互指向的Compsite Type


#1

想定义两个struct,它们的域会指向对方

Vertex = NTuple{3, Float64}

mutable struct Edge
    v1::Vertex
    v2::Vertex
    b1::Union{Nothing, Block}
    b2::Union{Nothing, Block}
end

mutable struct Block
    edges::Vector{Edge}
end
# code

这个代码在运行的时候 总会有个struct没有定义。
请问怎么处理这种情况?


#2

是不是只能用下面这种参数类型才能解决?

mutable struct Edge{T}
v1::Vertex
v2::Vertex
b1::Union{Nothing, T}
b2::Union{Nothing, T}
end


#3

Block 意义不强的话也可以写成这样:

mutable struct Edge
    v1::Vertex
    v2::Vertex
    b1::Union{Nothing, Vector{Edge}}
    b2::Union{Nothing, Vector{Edge}}
end

#4

是的,这是目前 Julia 里处理 forward declaration 的 workaround, 功能是一样的,只是以后可能会有语法糖。


#5

我觉得比较elegant的实现是声明一个abstract type(比如AbstractEdge)然后用参数类型,而不是Nothing(因为不符合performance tips)


#6

可否具体写明一下,感觉抽象类玩法还是驾驭不了。

另外,Union{T, nothing}会造成类型不稳定吗?

手册上说Union{T, Nothing} type can be used for function arguments, object fields and array element types as the equivalent of [ Nullable , Option or Maybe ] in other languages.

当然,这里可以直接用T,不用nothing。在构造的时候直接new的时候不赋值,让他是undef。


#7

应该会被优化掉,你的use case如果需要这样,就这样用就OK。