Julia Lang中声明枚举数据类型的不同方法

Julia Lang中声明枚举数据类型的不同方法,julia,Julia,使用@enum是声明Julia enum数据类型的唯一方法吗?如果是,为什么?这是唯一(简单)的方法,是的。答案,就像在朱莉娅身上经常(或者更确切地说,总是)一样,可以通过查看。 一开始这可能有点吓人,但过一段时间你就会习惯了 通常,要创建给定类型的对象,需要调用该类型的构造函数。 所以你可能希望能够做到 Enum(...) 并创建类型为Enum的对象 但是,在本例中,Enum是一个抽象类型,因此不能这样做 那么,@enum做什么呢?这个例子是 这实际上创建了一个全新的类型,称为水果,它是枚举

使用
@enum
是声明Julia enum数据类型的唯一方法吗?如果是,为什么?

这是唯一(简单)的方法,是的。答案,就像在朱莉娅身上经常(或者更确切地说,总是)一样,可以通过查看。 一开始这可能有点吓人,但过一段时间你就会习惯了

通常,要创建给定类型的对象,需要调用该类型的构造函数。 所以你可能希望能够做到

Enum(...)
并创建类型为
Enum
的对象

但是,在本例中,
Enum
是一个抽象类型,因此不能这样做

那么,
@enum
做什么呢?这个例子是

这实际上创建了一个全新的类型,称为
水果
,它是
枚举
的一个子类型,这种类型的对象称为
苹果
橙色
猕猴桃
,它们通过调用
Int(apple)
等转换为这些数字。这是通过生成Julia代码来实现的,在宏内部

原则上,你可以自己做宏所做的所有工作,但宏的存在是为了让我们的生活更轻松

编辑: 自Julia 0.7以来,可以使用您提到的
@enum
宏定义枚举,但也可以与begin块一起使用:

julia> @enum Fruit begin
           apple = 1
           orange = 2
           kiwi = 3
       end

julia> Fruit
Enum Fruit:
apple = 1
orange = 2
kiwi = 3

julia> apple
apple::Fruit = 1

julia> orange
orange::Fruit = 2

julia> kiwi
kiwi::Fruit = 3

julia> Int(orange)
2

julia> string(orange)
"orange"
也可以使用此begin块定义枚举,而无需指定值(在这种情况下,值从0开始,而不是从1开始)


…然后是滥用类型的方式;我在将类型作为集合的名称时偶然发现:

typealias Sunday Val{:Sunday}
typealias Monday Val{:Monday}
typealias Tuesday Val{:Tuesday}
typealias Wednesday Val{:Wednesday}
typealias Thursday Val{:Thursday}
typealias Friday Val{:Friday}
typealias Saturday Val{:Saturday}

typealias Days Union{
    Type{Sunday}, 
    Type{Monday}, 
    Type{Tuesday}, 
    Type{Wednesday}, 
    Type{Thursday}, 
    Type{Friday}, 
    Type{Saturday}
}

function daynumber(d::Days)
    if d == Sunday return 0
    elseif d == Monday return 1
    elseif d == Tuesday return 2
    elseif d == Wednesday return 3
    elseif d == Thursday return 4
    elseif d == Friday return 5
    elseif d == Wednesday return 6
    end
    -1
end

> daynumber(Friday)
  5
> daynumber(:Friday)
  > MethodError:`daynumber` has no method matching (::Symbol)
请注意,符号的使用只是一个相当多的反映,是完全多余的。你可以把任何东西放进去,然后通过型式检验把它恢复过来

> x = Saturday.parameters[1]
  :Saturday
> typeof(x)
  Symbol
> eval(x) == Saturday
  true
我很确定文档中明确推荐了这一点。然而@code_warntype并不特别反对这种构造

用集合论的术语来说,day alias是一种单例类型,因此是一组元素的名称。“类型”的“并集”是单元素集的集合论并集,形成枚举有限集类型

…还有更多类型混乱的枚举方法

abstract Fruits{N} <: Enum
immutable Apples <: Fruits{1} end
immutable Oranges <: Fruits{2} end
immutable Bananas <: Fruits{3} end

fruitsalad{N}(x::Fruits{N}) = N

> anorange = Oranges()
> fruitsalad(anorange)
  2
immutable Fruits{N} <: Enum
    apples::Fruits
    bananas::Fruits
    oranges::Fruits
    function Base.call(::Type{Fruits})
        new{"anything"}(
            Fruits{"crunchy"}(),
            Fruits{"mushy"}(),
            Fruits{"tangy"}()
        )
    end
    function Base.call{N}(::Type{Fruits{N}})
        if N != "crunchy" && N != "mushy" && N != "tangy"
            error("Invalid enumeration parameter")
        end
        new{N}()
    end
end

fruitsalad{N}(x::Fruits{N}) = N

> fruitsalad(Fruits().apples)
  "crunchy"

abstract Fruits{N}你可以使用
SuperEnum
(作者在这里)做一些很酷的事情:

using Pkg
Pkg.add("https://github.com/kindlychung/SuperEnum.jl")
using SuperEnum

@se Vehical plane train car truck

julia> Vehical.VehicalEnum
Enum Main.Vehical.VehicalEnum:
plane = 0
train = 1
car = 2
truck = 3

julia> Vehical.car
car::VehicalEnum = 2

julia> @se Lang zh=>"中文"*"Chinese" en=>"English" ja=>"日本语"
Main.Lang

julia> string(Lang.zh)
"中文Chinese"
immutable Fruits{N} <: Enum
    apples::Fruits
    bananas::Fruits
    oranges::Fruits
    function Base.call(::Type{Fruits})
        new{"anything"}(
            Fruits{"crunchy"}(),
            Fruits{"mushy"}(),
            Fruits{"tangy"}()
        )
    end
    function Base.call{N}(::Type{Fruits{N}})
        if N != "crunchy" && N != "mushy" && N != "tangy"
            error("Invalid enumeration parameter")
        end
        new{N}()
    end
end

fruitsalad{N}(x::Fruits{N}) = N

> fruitsalad(Fruits().apples)
  "crunchy"
using Pkg
Pkg.add("https://github.com/kindlychung/SuperEnum.jl")
using SuperEnum

@se Vehical plane train car truck

julia> Vehical.VehicalEnum
Enum Main.Vehical.VehicalEnum:
plane = 0
train = 1
car = 2
truck = 3

julia> Vehical.car
car::VehicalEnum = 2

julia> @se Lang zh=>"中文"*"Chinese" en=>"English" ja=>"日本语"
Main.Lang

julia> string(Lang.zh)
"中文Chinese"