从数组的源代码实现看,也是一个struct

    vlib/builtin/array.v

    1. println(arr.data) //返回数组地址:0x7ff0d2c01270
    2. println(arr.len) //返回5
    3. println(arr.cap) //返回5
    4. println(arr.element_size) //返回4

    数组定义

    根据首个元素的类型来决定数组的类型

    [1, 2, 3]的数组类型是[]int

    [‘a’, ‘b’]的数组类型是[]string

    数组元素的类型必须是一样的,不允许异构数组,[1, ‘a’] 编译不会通过

    固定长度数组

    对于固定长度数组来说,长度也是类型的一部分,[5]int和[6]int是两个不同的类型

    固定长度数组无法使用<<追加元素

    1. fn main() {
    2. mut arr := [8]int{} //声明长度固定的数组,所有数组元素默认都是0值初始化
    3. println(arr[1]) //返回0
    4. arr = [0, 1, 2, 3, 4, 5, 6, 7]! //初始化,注意数组后面有个!,否则会报错
    5. // arr = [0, 1, 2, 3, 4, 5, 6]! //报错,因为长度不匹配
    6. println(arr[1]) //赋值成功后,返回1
    7. println(arr[2]) //赋值成功后,返回2
    8. arr[2] = 222
    9. println(arr)
    10. println(arr.len) //固定长度数组,返回长度8
    11. // arr << 9 //报错,固定长度数组无法使用<<动态追加元素
    12. x := 2.32
    13. mut v := [8]f64{}
    14. println(v[1]) //返回0.000000
    15. v = [1.0, x, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]!
    16. println(v[1]) //赋值成功后,返回2.320000
    17. }

    数组初始化

    1. module main
    2. fn main() {
    3. //定义初始len为5,cap为20,初始值为10的数组
    4. mut arr := []int{len: 5, cap: 20, init: 10}
    5. println(arr) //输出[10, 10, 10, 10, 10]
    6. println('$arr.len,$arr.cap') //输出5,20
    7. arr << 3
    8. println(arr) //输出[10, 10, 10, 10, 10, 3]
    9. }

    定义一个指定长度,指定默认值的数组:

    1. arr := [0].repeat(50) //元素初始值为0,长度为50,容量为50
    2. println(arr.len) //返回50
    3. println(arr.cap) //返回50
    1. arr := ['a','b'].repeat(3) //元素初始值为a,b,重复3次,长度为6,容量为6
    2. println(arr.len) //返回6
    3. println(arr.cap) //返回6
    4. println(arr) //返回['a','b','a','b','a','b']

    数组的追加运算符: <<

    可以把一个元素追加到数组中,也可以把一个数组追加到数组中

    实际使用中需要注意的是 << 运算符是采用值复制的方式追加到数组中

    1. mut nums := [1, 2, 3, 4]
    2. println(nums) // "[1, 2, 3, 4]"
    3. nums << [5, 6, 7] //把一个数组追加到数组中
    4. println(nums) // "[1, 2, 3, 4, 5, 6, 7]"

    指针类型数组:

    1. mut arr := []&int{}
    2. b := 2
    3. c := 3
    4. arr << &a
    5. arr << &b
    6. arr << &c
    7. for i in arr {
    8. println(i) //输出数组的3个地址元素
    9. }

    判断元素是否在数组里

    1. names << 'Peter'
    2. names << 'Sam'
    3. println('Alex' in names) //false

    !in操作符

    in的反操作符,判断元素是否不在数组里

    1. println('aa' !in names) //true

    遍历数组

    1. numbers := [1, 2, 3, 4, 5]
    2. for num in numbers {
    3. println('num:$num')
    4. }
    5. for i, num in numbers {
    6. println('i:$i,num:$num')
    7. }
    8. //或者这种区间的写法也可以,不过不推荐使用,用上面的就够了
    9. for i in 0 .. numbers.len {
    10. println('num:${numbers[i]}')
    11. }

    数组切片/区间

    访问数组的错误处理

    当访问数组成员的索引越界或者别的错误,可以使用or代码块来进行错误处理

    1. module main
    2. fn main() {
    3. arr := [1, 2, 3]
    4. large_index := 999
    5. // var1:=arr[large_index] //直接报数组越界错误
    6. //增加or代码块后,可以进行错误的处理,而不是直接报错
    7. x := arr[large_index] or { panic('out of bounds') }
    8. println(x)
    9. myfn()
    10. }
    11. fn myfn() ? {
    12. arr:=[1,2,3]
    13. large_index:=999
    14. x := arr[large_index] ? //也可以本层级不处理,向上抛转错误
    15. println(x)
    16. }
    1. fn main() {
    2. mut a := [12.5, 6.5, -17.25]
    3. mut res := []f64{cap:2}
    4. for i in [1, 4] {
    5. // 检查数组a[i]是否存在,如果存在,则赋值,if条件返回true,如果不存在,则返回false
    6. if x := a[i] {
    7. res << x
    8. } else {
    9. res << -23.0
    10. }
    11. }
    12. println(res) //返回 [6.5, -23.0]
    13. }

    数组解构赋值

    目前数组的解构赋值只能用在传递给不确定参数函数,不像js中那样灵活

    1. module main
    2. a := ['a', 'b', 'c']
    3. println(variadic_fn_a(...a)) //数组解构赋值后,传递给不确定参数数组
    4. }
    5. fn variadic_fn_a(a ...string) string {
    6. return variadic_fn_b(...a) //数组解构赋值后,传递给不确定参数数组
    7. }
    8. fn variadic_fn_b(a ...string) string {
    9. a0 := a[0]
    10. a1 := a[1]
    11. a2 := a[2]
    12. return '$a0$a1$a2'
    13. }

    数组排序

    V语言提供了一个内置的数组排序语法,不仅可以对基本类型数组进行排序,也可以对结构体类型数组进行排序.

    1. module main
    2. struct User {
    3. age int
    4. name string
    5. }
    6. fn main() {
    7. //基本类型数组
    8. mut numbers := [1, 3, 2]
    9. numbers.sort() // 1, 2, 3,默认升序,即 a < b,小于号表示从小到大
    10. println(numbers)
    11. numbers.sort(a > b) // 3, 2, 1,降序排序,即 a > b,大于号表示从大到小
    12. // numbers.sort(aa > bb) // 只能用a和b这两个变量名,其他变量名会编译不通过
    13. println(numbers)
    14. //结构体类型数组
    15. mut users := [User{21, 'Bob'}, User{20, 'Zarkon'},
    16. User{25, 'Alice'},
    17. ]
    18. users.sort(a.age < b.age) //用结构体的某个字段进行排序
    19. println(users)
    20. users.sort(a.name > b.name) //字符串类型也可以排序
    21. println(users)
    22. }

    数组内置函数

    filter( ), map( ), any( ), all( )这四个内置函数都是在编译器内部实现的,比较特殊

    具体用法参考

    维度的数量不仅仅于1,2维,不限

    1. module main
    2. fn main() {
    3. // 2维数组
    4. a := [1, 2, 3]
    5. b := [4, 5, 6]
    6. c := [7, 8, 9]
    7. d := [[a, b, c], [b, c, a], [c, a, b]]
    8. println(d)
    9. println(d[0].len) //返回3
    10. println(d[0][0].len) //返回3
    11. // 2维数组
    12. mut aa := [][]int{len: 2, init: []int{len: 3}}
    13. aa[0][1] = 2
    14. println(aa) // [[0, 2, 0], [0, 0, 0]]
    15. // 3维数组
    16. mut aaa := [][][]int{len: 2, init: [][]int{len: 3, init: []int{len: 2}}}
    17. aaa[0][1][1] = 2

    数组相关的源代码可以参考v源代码中的:vlib/builtin/array.v

    更多数组相关的函数,参考标准库章节