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"