Использование кортежей имеет ключи в Джулии без инициализации словаря

Я новичок в Юлии. Для моего приложения у меня есть дорогостоящая операция по вычислению матрицы на основе двух точек. Вычисленные матрицы будут использоваться несколько раз, поэтому я решил кэшировать их в словаре. Однако я столкнулся со странным поведением Юлии. Если я добавлю первую пару (ключ, значение) как часть инициализации словаря, все будет работать так, как ожидалось. Однако, если я этого не сделаю и попытаюсь добавить свою первую пару (ключ, значение) позже, Джулия выйдет из строя.

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

А пока я просто добавлю вымышленную первую запись в словарь, но был бы признателен, если бы кто-нибудь поправил мою ошибку.

На всякий случай, если вы этого не знаете, нет необходимости включать сигнатуру сложного типа, если вы создаете экземпляр dict со значениями. Просто напишите: d = Dict((p1, p2) => "Hello world!"), и правильный тип будет определен автоматически. Вам нужно только указать тип, если вы хотите более разрешительную подпись.

DNF 07.04.2019 12:30

Это полезно, а я этого не знал. В моем реальном приложении (в отличие от этой игрушечной версии) я буду определять кеш заранее, поэтому сейчас мне понадобится подпись.

cpt_peter 07.04.2019 22:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
391
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет ничего лучше, чем задать мне вопрос в 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)])

Думал, что опубликую ответ, чтобы любой, кто также ударился головой о кирпичную стену, мог найти его полезным.

Другие вопросы по теме