Go语言学习笔记【3】 复杂数据类型

【声明】

非完全原创,部分内容来自于学习其他人的理论和B站视频。如果有侵权,请联系我,可以立即删除掉。

0、Go数据类型分类

引用类型包括:指针,slice,map,channel,接口,函数类型等,其本质是一个指向对象的指针
值类型有:数组、结构体、基本数据类型

一、指针

指针是一个代表着某个内存地址的值。这个内存地址往往是在内存中存储的另一个变量的值的起始位置

1、特点

(1)默认值 nil,没有 NULL null常量
(2)操作符 & 取变量地址,* 通过指针访问目标对象
(3)不支持指针运算,不支持 “->” 运算符,直接⽤ . 访问目标成员

2、基本使用

n := 66
var p *int = nil //声明一个变量p, 类型为 *int
p = &n
*p = 888 
fmt.Printf("n = %d, &n = 0x%x, *p = %d, p = 0x%x\n", n, &n, *p, p)

var p1 *int //声明方式1
p1 = new(int) //p1指向匿名的int变量
p2 := new(int) //声明方式2
*p2 = 111

output:
n = 888, &n = 0xc0000aa0c0, *p = 888, p = 0xc0000aa0c0

3、指针作为参数传递

func swap(x, y *int) {
   
    *x, *y = *y, *x
}

func main() {
   
    a := 6666
    b := 8888
    swap02(&a, &b) //变量值交换
    fmt.Printf("a = %d, b = %d\n", a, b)

二、数组

1、概念

数组是存储同一种数据类型多个元素的集合。它既可以存储基本数据类型,也可以存储引用数据类型。数组每个数据被称为数组元素,其包含的元素个数被称为数组的长度。

2、数组定义、遍历

声明明语法如下:
var 数组变量名 [数组长度]Type
注意:数组长度不能是变量

var n int = 6
var a [n]int  //err, non-constant array bound n
var b [10]int //方式1
c := [10]int{
   } //方式2:10个元素均为0
d := [...]int{
   1, 2, 3} //方式3:数组长度为3
e := [...]int{
   2: 6, 4: 8} //方式4:数组长度为5

//二位数组
f := [...][2]int{
   {
   0, 1}, {
   2, 3}, {
   4, 5}}  //方式1:第2维不能用...
g := [7][2]int{
   1: {
   0: 0}, 5: {
   1: 1}}  //方式2
h := [2][2]int{
   {
   0, 0}}


for i := 0; i < len[d]; i++ {
   
    fmt.Printf("d[%d] = %d\n", i, d[i])
}

//range具有两个返回值,第一个返回值是元素的数组下标,第二个返回值是元素的值
for i, v := range e {
   
    fmt.Println("e[", i, "]=", v)
}

数组的特点是:
(1)长度是固定的,因此定义时长度不能为变量,且数组定义后其长度不可修改
(2)数组是随机访问的,因为其地址是连续的,可以直接通过索引来计算访问的地址,时间为O(1)

func main(){
   
	a := [3][3]int8{
   }
	for i, val := range a {
   
		for j := 0; j < len(val); j++ {
   
			fmt.Printf("0x%x\t", &a[i][j])
		}
		fmt.Println()
	}
}

output:
0xc0000140b0	0xc0000140b1	0xc0000140b2	
0xc0000140b3	0xc0000140b4	0xc0000140b5	
0xc0000140b6	0xc0000140b7	0xc0000140b8

3、数组作为参数

go语言中,数组作为函数的参数时,默认以值的方式传递的,因此开销会比较大。
数组指针作为参数时,则是地址传递

func val_func(array [3]int) {
   
    array[0] = 6 // 值传递,此处修改不影响原数组
}

func addr_func(array *[3]int) {
   
    (*array)[0] = 6 //引用传递,此处修改会影响原数组
}

func main() {
   
    arr := [3]int{
   1, 2, 3}
    val_func(arr)
    fmt.Println(arr)
    addr_func(&arr)
    fmt.Println(arr)
}

output:
[1 2 3]
[6 2 3]

三、切片slice

由于数组的长度是确定的,且数组在定义后其长度无法再次修改,因此在遇到不确定长度的场景时,需要用到切片slice

切片并不是数组或数组指针,它通过内部指针和相关属性引⽤数组⽚段,以实现变⻓⽅案。它是一个引用类型

1、切片的声明

var s1 []int //和数组声明差不多,只是不需要指定长度
//make([]T, length, capacity) //capacity省略,则和length的值相同
var s2 []int = make([]int, 1, 2)
s3 := make([]int, 0, 0)
s4 := []int{
   1, 2} //创建切片并初始化

2、切片的操作

操作 含义
s[n] 切片s中索引位置为n的项
s[:] 从切片s的索引位置0到len(s)-1处所获得的切片
s[low:] 从切片s的索引位置low到len(s)-1处所获得的切片
s[:high] 从切片s的索引位置0到high处所获得的切片,len=high
s[low:high] 从切片s的索引位置low到high处所获得的切片,len=high-low
s[low:high:max] 从切片s的索引位置low到high处所获得的切片,len=high-low,cap=max-low
len(s) 切片s的长度,总是<=cap(s)
cap(s) 切片s的容量,总是>=len(s)
var s1 []int
//追加元素
s1 = append(s1, 1, 2)    //追加2个元素
fmt.Printf("s2 len = %d, cap = %d\n", len(s2), cap(s2))

//复制元素:部分覆盖
data := [...]int{
   0, 1, 2, 3, 4, 5}
s2 := data[3
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值