不变的字典

hr0*_*r0m 6 dictionary julia

有没有办法强制字典保持不变?

我有一个函数,它读取参数文件(并忽略注释)并将其存储在dict中:

function getparameters(filename::AbstractString)
    f = open(filename,"r")
    dict = Dict{AbstractString, AbstractString}()
    for ln in eachline(f)
        m = match(r"^\s*(?P<key>\w+)\s+(?P<value>[\w+-.]+)", ln) 
        if m != nothing
            dict[m[:key]] = m[:value]
        end
    end
    close(f)
    return dict
end
Run Code Online (Sandbox Code Playgroud)

这很好用.由于我有很多参数,我将最终在不同的地方使用,我的想法是让这个词是全局的.众所周知,全局变量并不那么好,所以我想确保dict及其成员是不可变的.

这是一个好方法吗?我该怎么做?我必须这样做吗?


奖金回答的东西:)

我的代码还行吗?(这是我用julia做的第一件事,来自c/c ++和python我倾向于以不同的方式做事.)我是否需要检查文件是否实际打开?我读的文件是"julia"吗?我也可以readall然后使用eachmatch.我没有看到"正确的方法"(如在python中).

Chr*_*kas 5

为什么不使用 ImmutableDict?它在基类中定义但未导出。您可以按如下方式使用之一:

julia> id = Base.ImmutableDict("key1"=>1)
Base.ImmutableDict{String,Int64} with 1 entry:
  "key1" => 1

julia> id["key1"]
1

julia> id["key1"] = 2
ERROR: MethodError: no method matching setindex!(::Base.ImmutableDict{String,Int64}, ::Int64, ::String)
 in eval(::Module, ::Any) at .\boot.jl:234
 in macro expansion at .\REPL.jl:92 [inlined]
 in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at .\event.jl:46

julia> id2 = Base.ImmutableDict(id,"key2"=>2)
Base.ImmutableDict{String,Int64} with 2 entries:
  "key2" => 2
  "key1" => 1

julia> id.value
1
Run Code Online (Sandbox Code Playgroud)

您可能想要定义一个构造函数,它接受一组对(或键和值)并使用该算法来定义整个字典(这是唯一的方法,请参阅底部的注释)。


补充一点,实际的内部表示是每个字典只包含一个键值对和一个字典。get 方法只是遍历字典检查它是否具有正确的值。这样做的原因是因为数组是可变的:如果您使用可变字段简单地构建了不可变类型,则该字段仍然是可变的,因此虽然id["key1"]=2行不通,id.keys[1]=2但可以。他们通过不使用可变类型来保存值(因此仅保存单个值)然后还保存一个不可变的字典来解决这个问题。如果您想直接在数组上进行这项工作,您可以使用ImmutableArrays.jl之类的东西,但我认为您不会获得性能优势,因为在检查密钥时您仍然需要循环遍历数组。 ..