Я новичок в Юлии. Для моего приложения у меня есть дорогостоящая операция по вычислению матрицы на основе двух точек. Вычисленные матрицы будут использоваться несколько раз, поэтому я решил кэшировать их в словаре. Однако я столкнулся со странным поведением Юлии. Если я добавлю первую пару (ключ, значение) как часть инициализации словаря, все будет работать так, как ожидалось. Однако, если я этого не сделаю и попытаюсь добавить свою первую пару (ключ, значение) позже, Джулия выйдет из строя.
p1 = [ 2.0, 1.0, 1.0]
p2 = [ 4.0, 2.0, 1.0]
# This works
my_dict = Dict{Tuple{Array{Float64,1}, Array{Float64,1}}, String}(
(p1, p2) => "hello world"
)
println(my_dict[(p1, p2)])
# This works
my_dict[ (p2, p1)] = "hello again"
println(my_dict[ (p2, p1)] )
# This doesn't
my_dict2 = Dict{Tuple{Array{Float64,1}, Array{Float64,1}}, String}
my_dict2[(p2, p1)] = "this fails with method dispatch error"
Вывод от Юлии:
julia complex_key_for_dict.jl
hello world
hello again
ERROR: LoadError: MethodError: no method matching setindex!(::Type{Dict{Tuple{Array{Float64,1},Array{Float64,1}},String}}, ::String, ::Tuple{Array{Float64,1},Array{Float64,1}})
Stacktrace:
[1] top-level scope at none:0
[2] include at ./boot.jl:326 [inlined]
[3] include_relative(::Module, ::String) at ./loading.jl:1038
[4] include(::Module, ::String) at ./sysimg.jl:29
[5] exec_options(::Base.JLOptions) at ./client.jl:267
[6] _start() at ./client.jl:436
in expression starting at /home/peter/julia/gps_analysis/complex_key_for_dict.jl:16
А пока я просто добавлю вымышленную первую запись в словарь, но был бы признателен, если бы кто-нибудь поправил мою ошибку.
Это полезно, а я этого не знал. В моем реальном приложении (в отличие от этой игрушечной версии) я буду определять кеш заранее, поэтому сейчас мне понадобится подпись.
Нет ничего лучше, чем задать мне вопрос в StackOverflow, чтобы понять, каким может быть решение. Это работает:
# This works. Added an open/close bracket to the end of the Dict defintion
my_dict2 = Dict{Tuple{Array{Float64,1}, Array{Float64,1}}, String}()
my_dict2[ (p2, p1)] = "this now works"
println(my_dict2[ (p2, p1)])
Думал, что опубликую ответ, чтобы любой, кто также ударился головой о кирпичную стену, мог найти его полезным.
На всякий случай, если вы этого не знаете, нет необходимости включать сигнатуру сложного типа, если вы создаете экземпляр dict со значениями. Просто напишите:
d = Dict((p1, p2) => "Hello world!")
, и правильный тип будет определен автоматически. Вам нужно только указать тип, если вы хотите более разрешительную подпись.