假设你想要 0 到 1000 之间所有的非负整数。 要是必须把它们一个个敲进数组里,那就太荒唐了。
为此,Julia 提供了range类型:
julia> 0:1000
0:1000
julia> typeof(0:1000)
UnitRange{Int64}
范围非常常见:它不仅省去了你手动输入的工作,也常作为函数的返回类型出现。
注意,范围并不是数组。
数组在创建时就已经确定(“贪婪”求值),需要的存储空间与数组长度成正比。
相比之下,范围只是一组用来生成序列的指令(“惰性”求值,也就是“迭代器”)。
如果你需要把范围当作数组使用,可以用 collect() 函数来转换:
julia> collect(0:5)
6-element Vector{Int64}:
0
1
2
3
4
5
也可以选用 collect(type, range) 来指定输出数组的类型。
步长可以自己指定,下面这个例子中是 0.3:
julia> collect(1.0:0.3:2.0)
4-element Vector{Float64}:
1.0
1.3
1.6
1.9
所以语法是 start:stepsize:stop。
两个端点都是包含在内的,就像整数示例中那样。
如果步长不能整除 stop - start,最后一个元素也不会超过 stop。
如果需要更精细的控制,可以使用 Base.range() 函数,它还提供了更多选项。
范围中也可以使用非数字序列。 最简单的例子是 ASCII 字母:
julia> 'a':'d'
'a':1:'d'
julia> typeof('a':'d')
StepRange{Char, Int64}
julia> collect('a':'d')
4-element Vector{Char}:
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
Char 类型会在另一个概念中更详细地介绍。
现在,只要把它当作放在单引号里的单个字符就行。
用 first() 和 last() 可以检查范围的边界。
判断某个特定的值是否属于某个范围,往往很有用。
实现这一功能的基础函数是 in(),但更常用的是中缀运算符 in,或者它更数学化的同义写法 ∈。
在合适的编辑器里,输入 ∈ 的快捷方式是 \in 再按 Tab 键。
r = 1:10 # => 1:10
first(r) # => 1
last(r) # => 10
7 in r # => true
11 ∈ r # => false
这里的 in 或 ∈ 运算符用在了范围上,但它也可以用于其他几种集合类型,比如向量、集合和字典。
整数范围和数组都可以用在数组下标中:
nums = collect(10.0:50.0)
nums[3:2:7] # gives [12.0, 14.0, 16.0]
nums[ [3, 5, 7] ] # also gives [12.0, 14.0, 16.0]
和 end 一起使用也可以,不过由于运算符优先级的关系,可能需要加括号:
nums[(end - 3):end]
4-element Vector{Float64}:
47.0
48.0
49.0
50.0
当然,下标里的任何一个元素都可以是已经存在的整数变量。