美文网首页
2019-04-16

2019-04-16

作者: Jesse_996 | 来源:发表于2019-04-16 18:31 被阅读0次

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

相关文章

网友评论

      本文标题:2019-04-16

      本文链接:https://www.haomeiwen.com/subject/pjibwqtx.html