在朱莉娅,我允许创作&使用静态字段?让我用简化的例子来解释我的问题。假设我们有一个类型:
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文件加载字典并将其存储到Foo类型中,其他两个变量baz
和qux_value
。现在,假设我将创建3个Foo对象类型。
vars = [ Foo("mydictfile.jld",38,37.0) for i=1:3]
在这里,正如您所看到的,所有Foo
个对象都加载了相同的字典。这是一个非常大的文件(~10GB),我不想多次加载它。所以,
我只是问,在朱莉娅有什么方法这样,我只加载一次,所有3种类型都可以达到它吗? (这就是我在问题中使用静态关键字的方式)
对于这样一个简单的问题,我的方法可能看起来很愚蠢,但作为下一步,我使这个Foo类型可迭代,我需要在next(d::Foo, state)
函数中使用这个字典。
修改
实际上,我现在已经找到了办法。但我想问一下这是否正确。
而不是将文件名赋给FOO
构造函数,如果我在创建对象之前将字典加载到变量中并将相同的变量赋予所有构造函数,我猜所有构造函数只是创建一个指针到同一个字典,而不是一次又一次地创建。我对吗 ?
因此,修改后的版本将是这样的:
dict = JLD.load("mydictfile.jld")["dict"]
vars = [ Foo(dict,38,37.0) for i=1:3]
顺便说一句,我仍然想听听我是否完全在Foo类型中做同样的事情(我的意思是构造函数)
答案 0 :(得分:1)
通过添加内部构造函数,您将使类型“过于特殊”。如果您不提供内部构造函数,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
,这也会提供更高效的代码,因为在您创建{{1}时将推断出类型参数K
和V
对象。请参阅Julia手册:http://docs.julialang.org/en/release-0.5/manual/performance-tips/#avoid-fields-with-abstract-containers
所以现在你可以在没有JLD文件的情况下尝试代码(例如我们没有):
Foo
你可以看到它确实是同一个字典(即只有一个引用实际存储在类型对象中),通过修改其中一个并看到其他字典也发生了变化,即它们指向同一个字典对象: / p>
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)