我可以在Julia中创建&使用静态字段?让我用一个简化的例子来解释我的问题。假设我们有一个类型:
type Foo
bar::Dict()
baz::Int
qux::Float64
function Foo(fname,baz_value,qux_value)
dict = JLD.load(fname)["dict"] # It is a simple dictionary loading from a special file
new(dict,baz_value,quz_value)
end
end
现在,正如您所看到的,我从jld文件中加载了一个字典,并将它与其他两个变量baz
和qux_value
一起存储到Foo类型中。现在,假设我要创建3个Foo对象类型。
vars = [ Foo("mydictfile.jld",38,37.0) for i=1:3]
在这里,你可以看到,所有的Foo
对象加载相同的字典。这是一个相当大的文件(~10GB),我不想多次加载它。所以,我只是问,在julia中有没有办法,让我只加载一次,所有的3种类型都能到达它?(这就是我在问题中使用Static关键字的方式)
对于这样一个简单的问题,我的方法可能看起来很愚蠢,但是作为下一步,我使这个Foo类型可迭代,并且我需要在next(d::Foo, state)
函数中使用这个字典。
编辑
事实上,我现在已经找到了一个方法。但我想问一下,这是否正确。而不是给FOO
构造函数文件名,如果我在创建对象之前将字典加载到变量中,并将相同的变量提供给所有构造函数,我猜所有构造函数只是创建一个指向相同字典的指针,而不是一次又一次地创建。我说的对吗?
那么,修改后的版本将是这样的:
dict = JLD.load("mydictfile.jld")["dict"]
vars = [ Foo(dict,38,37.0) for i=1:3]
顺便说一下,我仍然想知道如果我在Foo类型(我的意思是它的构造函数)中完全做同样的事情
通过添加内部构造函数使类型"太特殊"。如果你不提供内部构造函数,Julia会提供默认构造函数;它们只是在新类型的对象中填充字段。
你可以这样做:
immutable Foo{K,V}
bar::Dict{K,V}
baz::Int
qux::Float64
end
dict = JLD.load("mydictfile.jld")["dict"]
vars = [Foo(dict, i, i+1) for i in 1:3]
请注意,在类型定义中Dict
后面包含括号是一个语法错误。
{K,V}
使Foo
类型参数化,因此您可以在必要时创建不同类型的Foo
类型,其中包含不同的Dict
类型。即使您只将它用于单个类型的Dict
,这也将提供更高效的代码,因为类型参数K
和V
将在创建Foo
对象时推断出来。参见Julia手册:http://docs.julialang.org/en/release-0.5/manual/performance-tips/#avoid-fields-with-abstract-containers
julia> dict = Dict("a" => 1, "b" => 2)
julia> vars = [Foo(dict, i, Float64(i+1)) for i in 1:3]
3-element Array{Foo{String,Int64},1}:
Foo{String,Int64}(Dict("b"=>2,"a"=>1),1,2.0)
Foo{String,Int64}(Dict("b"=>2,"a"=>1),2,3.0)
Foo{String,Int64}(Dict("b"=>2,"a"=>1),3,4.0)
你可以看到它确实是同一个字典(即只有一个引用实际上存储在类型对象中),通过修改其中一个,看到其他的也发生了变化,即它们指向同一个字典对象:
julia> vars[1].bar["c"] = 10
10
julia> vars
3-element Array{Foo{String,Int64},1}:
Foo{String,Int64}(Dict("c"=>10,"b"=>2,"a"=>1),1,2.0)
Foo{String,Int64}(Dict("c"=>10,"b"=>2,"a"=>1),2,3.0)
Foo{String,Int64}(Dict("c"=>10,"b"=>2,"a"=>1),3,4.0)