首页 > 解决方案 > 用于与枚举进行切换或模式匹配的宏

问题描述

我想要一些语法糖来打开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

我什至可以执行以下操作:

function talk2(fruit::Fruit)
    say = ["I like apples.", "I like oranges.", "I like kiwis."]
    say[Int(fruit)]
end

但我不太喜欢 中的方法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
julia> talk3(apple)
"I like apples."

julia> talk3(orange)
"I like apples."

julia> talk3(kiwi)
"I like apples."

当然,在@match宏中我可以将 the强制转换Enum为 anInt并匹配 the Int,但这会妨碍开关的可读性。

有没有办法让Match.jl工作Enum?或者是否有来自不同包的宏可以打开Enum

标签: enumsjulia

解决方案


这可能是使用类型而不是枚举的主要原因。然后调度为你处理这个:

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."

正如https://pixorblog.wordpress.com/2018/02/23/julia-dispatch-enum-vs-type-comparison/指出的那样,此代码被编译器有效地内联。


推荐阅读