Array
数组是一个简单的固定长度容器。数组中的每个元素都具有相同的类型。数组的索引类型可以是任何序数类型。可以使用[]
构建数组
type
IntArray = array[0..5, int] # an array that is indexed with 0..5
var
x: IntArray
x = [1, 2, 3, 4, 5, 6]
for i in low(x)..high(x):
echo x[i]
数组是值类型,与任何其他Nim类型一样。赋值运算符复制整个数组内容。
内置的len proc返回数组的长度。low(a)返回数组a的最低有效索引,high(a)返回最高有效索引。
将数组从零开始是很常见的,因此有一个快捷语法来指定从零到指定索引减去一个的范围:
type
IntArray = array[0..5, int] # an array that is indexed with 0..5
QuickArray = array[6, int] # an array that is indexed with 0..5
Sequences
序列类似于数组,但动态长度可能在运行时期间发生变化(如字符串)。由于序列是可调整大小的,因此它们总是在堆上分配并收集垃圾。序列始终使用从位置0开始的int进行索引 。len,low和high操作也可用于序列。符号x [i]可用于访问x的第i个元素。序列可以由数组构造函数[]与数组一起构成序列运算符@。为序列分配空间的另一种方法是调用内置的newSeq过程。序列可以传递给openarray参数。
var
x: seq[int] # a reference to a sequence of integers
x = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence allocated on the heap
序列变量用@ []初始化
for value in @[3, 4, 5]:
echo value
# --> 3
# --> 4
# --> 5
for i, value in @[3, 4, 5]:
echo "index: ", $i, ", value:", $value
# --> index: 0, value:3
# --> index: 1, value:4
# --> index: 2, value:5
Open arrays
注意:Open arrays只能用于参数。
通常,固定大小的数组太不灵活了;程序应该能够处理不同大小的数组。open array类型允许这样做。始终使用从位置0开始的int索引Openarrays。对于open arrays,len,low和high操作也可用。具有兼容基类型的任何数组都可以传递给ope narray参数,索引类型无关紧要。
var
fruits: seq[string] # reference to a sequence of strings that is initialized with '@[]'
capitals: array[3, string] # array of strings with a fixed size
capitals = ["New York", "London", "Berlin"] # array 'capitals' allows assignment of only three elements
fruits.add("Banana") # sequence 'fruits' is dynamically expandable during runtime
fruits.add("Mango")
proc openArraySize(oa: openArray[string]): int =
oa.len
assert openArraySize(fruits) == 2 # procedure accepts a sequence as parameter
assert openArraySize(capitals) == 3 # but also an array type
Varargs
varargs参数类似于openarray参数。但是,它也是一种实现将可变数量的参数传递给过程的方法。编译器会自动将参数列表转换为数组
proc myWriteln(f: File, a: varargs[string]) =
for s in items(a):
write(f, s)
write(f, "\n")
myWriteln(stdout, "abc", "def", "xyz")
# is transformed by the compiler to:
myWriteln(stdout, ["abc", "def", "xyz"])
仅当varargs参数是过程标头中的最后一个参数时,才会执行此转换。
也可以在此上下文中执行类型转换:
proc myWriteln(f: File, a: varargs[string, `$`]) =
for s in items(a):
write(f, s)
write(f, "\n")
myWriteln(stdout, 123, "abc", 4.0)
# is transformed by the compiler to:
myWriteln(stdout, [$123, $"abc", $4.0])
Slice
切片看起来类似于语法中的子范围类型,但在不同的上下文中使用。切片只是Slice类型的一个对象,它包含两个边界a和b。切片本身并不是很有用,但其他集合类型定义了接受Slice对象来定义范围的运算符。
var
a = "Nim is a progamming language"
b = "Slices are useless."
echo a[7..12] # --> 'a prog'
b[11..^2] = "useful"
echo b # --> 'Slices are useful.'
"Slices are useless."
| | |
0 11 17 using indices
^19 ^8 ^2 using ^ syntax
Tuples
元组类型定义各种命名字段和字段的顺序。构造函数()可用于构造元组。构造函数中字段的顺序必须与元组定义中的顺序匹配。如果不同的元组类型以相同的顺序指定相同类型和相同名称的字段,则它们是等效的。元组的赋值运算符复制每个组件。符号t.field
用于访问元组的字段。另一种表示法是t [i]
访问第i个字段。这里i
必须是一个常数整数
type
Person = tuple[name: string, age: int] # type representing a person:
# a person consists of a name
# and an age
var
person: Person
person = (name: "Peter", age: 30)
# the same, but less readable:
person = ("Peter", 30)
echo person.name # "Peter"
echo person.age # 30
echo person[0] # "Peter"
echo person[1] # 30
# You don't need to declare tuples in a separate type section.
var building: tuple[street: string, number: int]
building = ("Rue del Percebe", 13)
echo building.street
# The following line does not compile, they are different tuples!
#person = building
# --> Error: type mismatch: got (tuple[street: string, number: int])
# but expected 'Person'
# The following works because the field names and types are the same.
var teacher: tuple[name: string, age: int] = ("Mark", 42)
person = teacher
在变量赋值期间可以解包元组(并且只有这样!)。这可以很方便地将元组的字段直接分配给单独命名的变量。一个例子是os模块中的splitFile proc,它同时返回路径的目录,名称和扩展名。要使元组解包工作,您必须在要分配解包的值周围使用括号,否则您将为所有单个变量分配相同的值!例如:
import os
let
path = "usr/local/nimc.html"
(dir, name, ext) = splitFile(path)
baddir, badname, badext = splitFile(path)
echo dir # outputs `usr/local`
echo name # outputs `nimc`
echo ext # outputs `.html`
# All the following output the same line:
# `(dir: usr/local, name: nimc, ext: .html)`
echo baddir
echo badname
echo badext
网友评论