我想要一些语法糖来打开Enum. 当然,一个if else块按预期工作:
@enum Fruit apple=1 orange=2 kiwi=3
function talk1(fruit::Fruit)
if fruit == apple
"I like apples."
elseif fruit == orange
"I like oranges."
else
"I like kiwis."
end
end
Run Code Online (Sandbox Code Playgroud)
我什至可以执行以下操作:
function talk2(fruit::Fruit)
say = ["I like apples.", "I like oranges.", "I like kiwis."]
say[Int(fruit)]
end
Run Code Online (Sandbox Code Playgroud)
但我不太喜欢 中的方法talk2,因为它分配了一个向量并且可读性较差。我尝试了Match.jl包,但我似乎无法匹配Enum:
using Match
function talk3(fruit::Fruit)
@match fruit begin
apple => "I like apples."
orange => "I like oranges."
kiwi => "I like kiwis."
end
end
Run Code Online (Sandbox Code Playgroud)
julia> talk3(apple)
"I like apples."
julia> talk3(orange)
"I like apples."
julia> talk3(kiwi)
"I like apples."
Run Code Online (Sandbox Code Playgroud)
当然,在@match宏中,我可以将 转换Enum为 anInt并匹配Int,但这会妨碍开关的可读性。
有没有办法让Match.jl在一个Enum? 或者是否有来自不同包的宏可以打开Enum?
这可能是使用类型而不是枚举的主要原因。然后 dispatch 为你处理这个:
abstract type Fruit end
struct Apple <: Fruit end
struct Orange <: Fruit end
struct Kiwi <: Fruit end
talk(fruit::Apple) = "I like apples."
talk(fruit::Orange) = "I like oranges."
talk(fruit::Fruit) = "I like kiwis."
Run Code Online (Sandbox Code Playgroud)
正如https://pixorblog.wordpress.com/2018/02/23/julia-dispatch-enum-vs-type-comparison/指出的那样,编译器有效地内联了此代码。
虽然我实际上很喜欢你的talk2()功能,但我想你可以通过使用来提高可读性Dict:
function talk(fruit::Fruit)
phrases=Dict{Int,String}([
(Int(apple) => "I like apples"),
# or: (1->"I like apples"), or: (1,"I like apples")
(Int(orange) => "I like oranges"),
(Int(kiwi) => "I like kiwis")
])
phrases[Int(fruit)]
end
Run Code Online (Sandbox Code Playgroud)
或者:
function talk(fruit::Fruit)
phrases=Dict{Fruit,String}(
apple=>"I like apples",
orange=>"I like oranges",
kiwi=>"I like kiwis"
)
phrases[fruit]
end
Run Code Online (Sandbox Code Playgroud)
注意:这意味着您甚至不需要声明函数,而只需依赖phrases[fruit]即可;然而,这将给出“较弱”的警告,即“找不到密钥”错误而不是“MethodError”(@enum Veg tomato=1例如,如果您给它一个 ),从长远来看,这可能会使调试变得更加困难。
如果您想使用Match.jl,我认为您需要评估::Int(fruit), not上的潜在匹配::Fruit(所有三个案例talk3()都是 Fruit 类型!),即:
function talk3(fruit::Fruit)
@match Int(fruit_int) begin
1 => "I like apples."
2 => "I like oranges."
3 => "I like kiwis."
end
end
Run Code Online (Sandbox Code Playgroud)
或使用string()以下部分enum:
function talk4(fruit::Fruit)
@match string(fruit) begin
"apple" => "I like apples."
"orange" => "I like oranges."
"kiwi" => "I like kiwis."
end
end
Run Code Online (Sandbox Code Playgroud)