初始化一个结构字段,它是 Julia 中的一个向量
Initializing a struct field that is a vector in Julia
我有以下可变结构:
mutable struct foo
x::Vector{String}
# other field(s)...
# constructor(s)
end
我想从这个结构创建一个对象并像下面这样编辑它:
bar = foo() # or some other constructor
push!(bar.x, "a")
# Do some stuff...
push!(bar.x, "b")
# Do some more stuff...
push!(bar.x, "c")
为此,foo
的最佳构造函数是什么?
P.S。我尝试了以下构造函数:
foo() = new()
如果我使用它并执行 push!(bar.x, "a")
,我会得到一个 UndefRefError
。我可以在外部初始化 bar.x
(如 bar.x = []
),但我真的想避免这种情况。
我也试过:
foo() = new([])
有了这个,我就可以毫无问题地进行推送操作了。但是,如果我在结构中还有许多其他字段也是向量,我将不得不这样做:
mutable struct foo
x::Vector{String}
y::Vector{String}
z::Vector{String}
w::Vector{String}
# maybe dozens more...
foo() = new([], [], [], [], ...) # kind of ugly and wastes time to type
end
这是最好的吗?
你可以这样做:
julia> mutable struct Foo
x::Vector{String}
Foo() = new(String[])
end
julia> Foo()
Foo(String[])
但是,对于您的情况,最方便的是 Base.@kwdef
:
Base.@kwdef mutable struct FooB
x::Vector{String} = String[]
y::Vector{String} = String[]
end
现在当然可以了:
julia> FooB()
FooB(String[], String[])
但是也可以使用其他方法:
julia> methods(FooB)
# 3 methods for type constructor:
[1] FooB(; x, y) in Main at util.jl:478
[2] FooB(x::Vector{String}, y::Vector{String}) in Main at REPL[9]:2
[3] FooB(x, y) in Main at REPL[9]:2
所以你可以这样做:
julia> FooB(;y=["hello","world"])
FooB(String[], ["hello", "world"])
有一种替代方法非常简洁,几乎与写出输入一样快:
struct Foo # Typenames should be uppercase
x::Vector{String}
y::Vector{String}
z::Vector{String}
w::Vector{String}
Foo() = new((String[] for _ in 1:4)...) # using a generator and splatting
# Foo() = new(ntuple(_->String[], 4)...) # also possible
end
我有以下可变结构:
mutable struct foo
x::Vector{String}
# other field(s)...
# constructor(s)
end
我想从这个结构创建一个对象并像下面这样编辑它:
bar = foo() # or some other constructor
push!(bar.x, "a")
# Do some stuff...
push!(bar.x, "b")
# Do some more stuff...
push!(bar.x, "c")
为此,foo
的最佳构造函数是什么?
P.S。我尝试了以下构造函数:
foo() = new()
如果我使用它并执行 push!(bar.x, "a")
,我会得到一个 UndefRefError
。我可以在外部初始化 bar.x
(如 bar.x = []
),但我真的想避免这种情况。
我也试过:
foo() = new([])
有了这个,我就可以毫无问题地进行推送操作了。但是,如果我在结构中还有许多其他字段也是向量,我将不得不这样做:
mutable struct foo
x::Vector{String}
y::Vector{String}
z::Vector{String}
w::Vector{String}
# maybe dozens more...
foo() = new([], [], [], [], ...) # kind of ugly and wastes time to type
end
这是最好的吗?
你可以这样做:
julia> mutable struct Foo
x::Vector{String}
Foo() = new(String[])
end
julia> Foo()
Foo(String[])
但是,对于您的情况,最方便的是 Base.@kwdef
:
Base.@kwdef mutable struct FooB
x::Vector{String} = String[]
y::Vector{String} = String[]
end
现在当然可以了:
julia> FooB()
FooB(String[], String[])
但是也可以使用其他方法:
julia> methods(FooB)
# 3 methods for type constructor:
[1] FooB(; x, y) in Main at util.jl:478
[2] FooB(x::Vector{String}, y::Vector{String}) in Main at REPL[9]:2
[3] FooB(x, y) in Main at REPL[9]:2
所以你可以这样做:
julia> FooB(;y=["hello","world"])
FooB(String[], ["hello", "world"])
有一种替代方法非常简洁,几乎与写出输入一样快:
struct Foo # Typenames should be uppercase
x::Vector{String}
y::Vector{String}
z::Vector{String}
w::Vector{String}
Foo() = new((String[] for _ in 1:4)...) # using a generator and splatting
# Foo() = new(ntuple(_->String[], 4)...) # also possible
end