Я бы хотел избежать использования уродливых имен перечислений с префиксом, таких как direction_right. Интересно, можно ли использовать символические имена перечислений?
Проблема: код ниже не будет работать из-за имен конфликтов перечислений.
@enum Align top right bottom left
@enum Direction up right down left
function play(d::Direction)
print(d)
end
play(right)
Можно ли вместо этого использовать что-то подобное?
@enum Align :top :right :bottom :left
@enum Direction :up :right :down :left
function play(d::Direction)
print(d)
end
play(:right)
Я хотел бы обеспечить безопасность типов и указать тип Direction для аргумента play.





Вы можете использовать Symbol в сочетании с Val и, следовательно, иметь возможность отправлять по типу (или по значению, если необходимо)
const Direction = Union{[Val{d} for d in [:up, :right, :down, :left]]...}
function direct(d::Direction)
println(typeof{d})
end
direct(s::Symbol)=direct(Val{s}())
Теперь вы можете сделать:
julia> direct(:up)
Val{:up}
julia> direct(:up1)
ERROR: MethodError: no method matching direct(::Val{:up1})
Приятно, спасибо. Знаете ли вы, есть ли у этого подхода какие-либо недостатки, такие как снижение производительности или некоторые осложнения?
Этот подход работает быстро после создания Val{:symbol}(). Он использует типы для множественной отправки, поэтому не уступает любому другому коду Julia. Следовательно, вы можете использовать его в своем производственном коде.
Кажется, это то же самое, что и другой вопрос, но с немного другим символическим предложением: stackoverflow.com/questions/78526825/…. Как отмечалось в обсуждении, вы создаете утверждения конфликтующих типов, и символические имена в этом не помогут.