前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go复合数据类型数组和切片

Go复合数据类型数组和切片

作者头像
Wyc
发布2023-02-27 16:33:14
3870
发布2023-02-27 16:33:14
举报
文章被收录于专栏:Python研发Python研发

数组

声明&&初始化数组

  • 数组声明需要指定元素及元素个数,语法格式如下
  • 数组用来存储相同唯一类型的,一组已编号且长度固定的序列

var arr_name[num] arr_type

代码语言:javascript
复制
package main

import "fmt"

func main()  {
	// 写添加元素的个数
	var test [5]string
	fmt.Println(test)
	for i:=0; i< 4; i++{
		test[i+1] = "test"
	}
	fmt.Println(test)
	// 不写添加元素的个数, 动态加载列表
	var arry = [...]int{1, 2, 3, 4, 5, 6}
	fmt.Println(arry)
}
/*
结果
[ test test test test]
[1 2 3 4 5 6]
*/
  • 索引元素[下标]
代码语言:javascript
复制
package main

import "fmt"

func main()  {
	var test = [...]string{"1","2","3","4"}
	fmt.Println(test[2])
}
// 结果 3
  • 索引越界报错 invalid argument: index 10 out of bounds
  • 索引越界报错,骗过编译器 panic 用一个变量表示索引
代码语言:javascript
复制
package main

import "fmt"

func main()  {
	var idx = 10
	var test = [...]string{"1","2","3","4"}
	fmt.Println(test[idx])
}
// 报错 骗过编译器越界

指针数组

  • 数组的元素除了是某个类型外,还可以是某个类型的指针
  • new函数返回一个TYPE类型的数据结构划分内存并执行默认的初始化操作,然后返回这个数据对象的指针
  • 只声明不初始化,必须用new,
  • 两个数组指针直接复制
代码语言:javascript
复制
package main

import "fmt"

func main()  {
	var arry1 [5] *int
	fmt.Println(arry1)
	arry1[0] = new(int)
	arry1[1] = new(int)
	arry1[2] = new(int)
	arry1[3] = new(int)
	arry1[4] = new(int)
	*arry1[0] =10
	*arry1[1] =10
	*arry1[2] =10
	*arry1[3] =10
	*arry1[4] =10
	fmt.Println(arry1)
	for i:=0; i < len(arry1); i++{
		fmt.Printf("%v\n",*arry1[i])
		fmt.Printf("%v\n",arry1[i])
	}

}
// 结果
/*
[<nil> <nil> <nil> <nil> <nil>]
[0xc00001e0b0 0xc00001e0b8 0xc00001e0c0 0xc00001e0c8 0xc00001e0d0]
10
10
10
10
10
*/
  • 两个数组指针复制
    • 内部存放的是指针,指向同一块地址,直接赋值,内容都一样,看起来是浅拷贝,
    • 但其实是深拷贝
    • 判定依据两个数据指针不同就是深拷贝,指针地址相同就是浅拷贝
代码语言:javascript
复制
package main

import "fmt"

func main()  {
	var arry1 [3]*string
	arry2 := [3]*string{new(string), new(string), new(string)}
	fmt.Println(arry1)
	fmt.Println(arry2)
	arry1 = arry2
	fmt.Println(arry1)
	for i:=0; i < len(arry2); i++ {
		fmt.Printf("%d, %v, %v\n", i, arry1[i], *arry1[i])
		fmt.Printf("%d, %v, %v\n", i, arry2[i], *arry2[i])
	}

}
/*
结果
[<nil> <nil> <nil>]
[0xc000014260 0xc000014270 0xc000014280]
[0xc000014260 0xc000014270 0xc000014280]
0, 0xc000014260,
0, 0xc000014260,
1, 0xc000014270,
1, 0xc000014270,
2, 0xc000014280,
2, 0xc000014280,
*/

数组指针

  • 数组是一个值类型,所有的值类型变量在赋值和作为参数传递时都将产生一次复制操作
  • 从内存和性能上来看,在函数间船队数组是一个开销很大的操作,因为无论这数组有多厂,都会完整复制,并传递给函数
  • 数组指针只需要很小传递
代码语言:javascript
复制
package main

import (
	"fmt"
	"unsafe"
)

func bigArryPoint(arr *[1e6]int64)  {
	fmt.Printf("[数组指针复制:大小:%d 字节]\n", unsafe.Sizeof(arr))

}

func bigArry(arr [1e6]int64){
	fmt.Printf("[数组复制:大小:%d 字节]\n", unsafe.Sizeof(arr))

}

func main()  {
	var arry [1e6]int64
	bigArry(arry)
	bigArryPoint(&arry)

}
/*
[数组复制:大小:8000000 字节]
[数组指针复制:大小:8 字节]
*/

多维数组

  • 多维数组的典型用例是平面坐标(而为数组)和三维坐标(三维数组)
  • Golang的数组本身只有一个唯独,但是我们可以组合多个数组从而创建出多维数组
代码语言:javascript
复制
package main

import (
	"fmt"
	"unsafe"
)

func bigArryPoint(arr *[1e6]int64)  {
	fmt.Printf("[数组指针复制:大小:%d 字节]\n", unsafe.Sizeof(arr))

}

func bigArry(arr [1e6]int64){
	fmt.Printf("[数组复制:大小:%d 字节]\n", unsafe.Sizeof(arr))

}

func main()  {
	arry := [4][2] int{{1, 2},{10, 20},{30, 40},{50, 60}}
	fmt.Println(arry[3])
	fmt.Println(arry[3][0])


}
/*
结果
[50 60]
50
*/

切片

  • 切片是围绕动态数据来构建的
  • 数组一旦创建就不能更改长度,但是切片可以按需求自动增长和缩小
  • 增长是使用内置的append函数来实现的
  • 缩小通过对切片的再次切片来实现
声明和初始化

var直接声明

代码语言:javascript
复制
package main

import (
	"fmt"
)



func main()  {

	var s1 []int
	fmt.Println(s1)
	s1 = append(s1, 1)
	s1 = append(s1, 1)
	s1 = append(s1, 1)
	fmt.Println(s1)

	var s2 = []int{1,2,3}
	fmt.Println(s2)
}

使用make

  • make([]类型, 长度, 容量)
  • 以类型0值+容量的个数填充slice
代码语言:javascript
复制
package main

import "fmt"

func main()  {
	// 使用make初始化一个长度为0的slice
	var s1 = make([]int, 0)
	s1 = append(s1, 1)
	s1 = append(s1, 2)
	s1 = append(s1, 3)
	fmt.Println(s1)
	// 使用make,初始化一个长度为5,容量为5的slice
	var s2 = make([]int, 5, 5)
	s2 = append(s2, 1)
	s2 = append(s2, 2)
	s2 = append(s2, 3)
	fmt.Println(s2)
}

/*
结果
[1 2 3]
[0 0 0 0 0 1 2 3]

*/
  • new和make对比
    • 简单说new只分配内存,make用于slice,map,和channel的初始化。
    • 对比表格

函数名

适用范围

返回值

填充值

new

new可以对所有类型进行内存分配

new返回指针

new填充零值

make

make只能创建类型(slice、map、channel)

make返回引用

make填充非零值

通过切片创建新的切片

  • 语法如下 slice[start:end:cap]
  • 其中start表示从slice的第几个元素开始
  • end控制切片的长度(end-i)
  • cap控制切片的容量,如果没有给定cap,slice的长度值,则表示到底层数组的最尾部
  • 新切片的长度 = end-start
  • 新切片的容量 = cap-start
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数组
    • 声明&&初始化数组
      • 指针数组
        • 数组指针
          • 多维数组
            • 切片
              • 声明和初始化
            • 通过切片创建新的切片
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档