Julia元组

Julia元组

1.定义
元组(Tuple)是由多个元素构成的组合结构,且元素的类型及个数都可不受限制;但是一旦创建,对象便不可变,其中的元素类型、值及个数都无法再修改。基本的定义形式为:

(元素1, 元素2, ... , 元素n)

其中,圆括号为界定符,元素之间用逗号分开。例如:

julia> typeof((1, "foo",2.5))
Tuple{Int64, String, Float64}

可见Julia会根据元素值自动创建形如Tuple{T1, T2, …}的元组对象。

在无歧义的情况下,可以省略圆括号,以逗号连接的多元素直接创建元组,例如:
Julia元组

不过对于单元素的元素,为避免歧义,一般需在其尾部附加一个逗号,即(元素,)。例如:

julia> (1, )
(1, )

julia> typeof(ans)
Tuple{Int64}

另外,元组是协变的,所以如下这种特性会在多态分发时发挥作用:

julia> Tuple{Int} <: Tuple{Integer}
true

julia> Tuple{Int, AbstractString} <: Tuple{Real, Any}
true

julia> Tuple{Int, AbstractString} <: Tuple{Real, Real}
false

julia> Tuple{Int, AbstractString} <: Tuple{Real, }
false

2.展开
创建元组对象时,可将已有的元组通过...操作符(展开操作符)展开到新元组中。例如:

julia> (1, 2, (10.5, "abc")..., 3)
(1, 2, 10.5, "abc", 3)

当然,对于某个元组变量也是适用的:
Julia元组

需注意的是,下面的用法是不会成功的:

julia> (a...)
ERROR: syntax: "..." expression outside call

显然,这是一个语法错误,即Julia并不支持这样的展开操作,正确的做法是:

julia> (a..., )      # 注意...之后的逗号
(10.5, "abc")

即需要在展开符之后再附加一个逗号。

3.元素访问
如果要访问元组对象的元素,使用方括号并给定索引值(1-based)即可,例如:

julia> a[1]         # 访问第1个元素
 10.5

julia> a[2]         # 访问第2个元素
"abc"

但内部元素不可改变:
Julia元组

例中试图修改a的第1个元素,结果报错,因为元组是不可变的。

还有一种提取元组元素的方法,即直接提供变量列表,将其中的元素“提取”到对应位置的变量中。例如:

julia> x, y = a
(10.5, "abc")

julia> x
10.5

julia> y
"abc"

提供变量的个数可以少于元组长度,但不能多,否则会报BoundsError错误。

4.命名元组
命名元组(Named Tuple)是另外一种类型的元组,与上述的普通元组的区别在于,每个元素能够附加一个名字,基本的定义形式为:

(名1=元素1, 名2=元素2, ... , 名n=元素n)

例如:

julia> nt1 = (a=1, b=2, c=3.8, d=8//9)     # 四个字段的命名元组
(a = 1, b = 2, c = 3.8, d = 8//9)

julia> typeof(nt1)
NamedTuple{(:a, :b, :c, :d), Tuple{Int64, Int64, Float64, Rational{Int64}}}

其中的名称与元素值可视为键值对,在定义命名元组时各个名称是不能重复的,否则会报错:

julia> (a=1, a=2)
ERROR: syntax: field name "a" repeated in named tuple

但需要注意的是,以这种方式创建命名元组的对象时,界定圆括号不再能省略,否则会出现错误。

在结构上,命名元组的类型为NamedTuple,是一个参数化复合类型,包括两个部分,一部分是元素为Symbol类型的普通元组,用于记录命名元组内部各元素的名称;另一部分是记录着各元素类型的元组。例如前例中的nt1命名元组,其第一个类参为常量(:a, :b, :c, :d),是四个元素的名称元组,而另一个类参Tuple{Int64, Int64, Float64, Rational{Int64}}表示nt1的元素类型依次是两个整型Int64、浮点型Float64与有理型Rational{Int64}

在构造命名元组时,自然也可以通过其构造方法创建对象,例如:

julia> nt2 = NamedTuple{(:a, :b), Tuple{Float32, String}}((1, ""))
(a = 1.0f0, b = "")

在创建对象时,类型中可同时提供名称元组与类型元组,也可只提供名称元组,由Julia自动确定类型。例如:

julia> nt3 = NamedTuple{(:a, :b)}((1, ""))
(a = 1, b = "")

对于命名元组对象,元素的访问除了采用普通元组的下标索引方式外,还可使用元素的名称进行访问。例如:

julia> nt3.a, nt3.b
(1, "")

julia> nt2.a, nt2.b
(1.0f0, "")

julia> nt1.a, nt1.b, nt1.c, nt1.d
(1, 2, 3.8, 8//9)

这种访问方式不但直观,而且在性能上并不弱于下标索引方式。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!