Golang学习笔记(复合数据类型)

复合数据类型有指针、数组、切片、字典(map)、通道、结构和接口,

指针

指针的声明类型为*T, Go 同样支持多级指针**T。通过在变量名前加&来获取变量的地址。特点如下:
  1. 在赋值语句中,*T出现在“=”左边表示指针声明,在右边表示取指针指向的值(varName为变量名),如下:
var a = 11
p := &a //*p和a的值都是11
  1. 结构体指针访问结构体字段仍然使用‘.’,Go语言没有“—>”操作符。例如:
	type User struct{
		name string
		age int
	}
	andes := User{
		name: "andes",
		age: 18,
	}
	p :=&andes
	fmt.Println(p.name) //p.name 通过“.”操作符访问成员变量
  1. Go不支持指针运算
a := 1234 
P := &a 
p++  //不允许 报non-numeric type*int 错误

  1. 函数中允许返回局部变量的地址

    Go 编译器使用“战逃逸 机制将这种局部变 分配在堆上。 例如:
    
	func sum (a , b int) *int{
	sum := a+b 
	return &sum //允许,sum会分配在heap上
}
	package main
	 
	type Student struct {
	    Name string
	    Age  int
	}
	 
	func StudentRegister(name string, age int) *Student {
	    s := new(Student) //局部变量s逃逸到堆
	 
	    s.Name = name
	    s.Age = age
	 
	    return s
	}
	 
	func main() {
	    StudentRegister("Jim", 18)
	}

数组

数组的类型名是[n]elemetType,其中n是长度,elemetType是类型。比如一个包含3个int类型的数组表示为[3]int。
数组一般在创建时通过字面变量进行初始化,单独声明一个数组类型的变量而不进行初始化是没有意义的
var arr [2]int //声明一个有两个整型的数纽,但元素默认值是0,一般很少这样使用
arry := [...]float64{7.0,8.5,9.1} //[...]后面跟着字面变量初始化列表

**数组初始化**
a := [3]int{1,2,3} //指定长度和初始化字面变量
a := [...]int{1,2,3} //不指定长度,但是根据后面的初始化值确定长度
a := [3]int{1:1,2:3} //指定总长度,并通过索引值进行初始化,没有初始化元素时使用类型默认值
a := [...]int{1:1,2:3} //不指定总长度,通过索引值进行初始化,数组长度由最后一个索引值确定,没有指定索引的元素被初始化为类型的零值
**数组特点**
	1、数组创建完长度固定了,不可以再追加元素
	2、数组是值类型的,数组复值或作为函数都是值拷贝
	3、数组长度是数组类型的组成部分,[10]int和[20]int表示不同的类型。
	4、可以根据数组创建切片
**数组相关操作**
(1)数组元素访问。示例如下:
a := [...]int{1,2,3}
b := a[0]
for i,v := range a{
}
(2) 数组长度。示例如下:
a := [...]{1,2,3}
alength := len(a)

for i:=0; i<alength;i++{
}

切片

切片是一种变长数组,其数据结构中有指向数组的指针,所以它是一种引用类型。例如:

	type slice struct {
		arrary unsafe.Pointer
		len    int
		cap    int 
}

Go为切片维护三个元素——指向底层数组的指针、切片的元素数量和底层数组的容量。
在这里插入图片描述

  • 切片的创建

  • 由数组创建

     创建语法如下:array[b:e] 其中array 表示数组名;b表示开始索引,可以不指定,默认是0;e表示结束索引,可以不指定,默认是len(array)。array[b:e]表示创建一个包含e-b个元素的切片,第一个元素是array[b],最后一个元素是array[e-1].例如:
    
	var array = [...]int{0,1,2,3,4,5,6} //创建有7个int型元素的数组
	s1 := array[0:4]
	s2 := array[:4]
	s3 := array[2:]
	fmt.printf{"%v\n",s1} //[0 1 2 3]
	fmt.printf{"%v\n",s2} //[0 1 2 3]
	fmt.printf{"%v\n",s3} //[2 3 4 5 6]
  • 通过内置函数make创建切片

注意:由make创建的切片各元素默认初始化为切片元素类型的零值。例如:

	//len=10,cap=10
	a := make([]int,10)
	
	//len=10,cap=15
	b :=make([]int,10,15)
	
	fmt.printf{"%v\n",a} //结果为[0 0 0 0 0 0 0 0 0 0]
	fmt.printf{"%v\n",a} //结果为[0 0 0 0 0 0 0 0 0 0]

直接声明切片类型是没有意义的。例如:

	var a []int 
	fmt.printf{"%v\n",a} //结果为[]

此时切片a的底层数据结构如下图:
在这里插入图片描述

  • 切片支持的操作

  • 内置函数len()返回切片长度

  • 内置函数cap()返回切片底层数组容量

  • 内置函数append()对切片追加元素

  • 内置函数copy()用于复制一个切片

示例:

a := [...]int{0,1,2,3,4,5,6}
b := make([]int,2,4)
c :=a[0:3]

fmt.Println(len(b)) //2
fmt.Println(cap(b)) //4

b=append(b,1)
fmt.Println(b) //[0 0 1]
fmt.Println(len(b)) //3
fmt.Println(cap(b)) //4

b=append(b,c...)
fmt.Println(b) //[0 0 1 0 1 2]
fmt.Println(len(b)) //6
fmt.Println(cap(b)) //8 底层数组发生扩展

d :=make([]int,2,2)
copy(d,c) //copy只会复制d和c中长度最小的
fmt.Println(d) //[0 1]
fmt.Println(len(d)) //2
fmt.Println(cap(d)) //2 底层数组容量
  • 字符串和切片的相关转化;例如:
str := "hello,世界!" //通过字符串字面两初始化一个字符串 str
a :=[]byte(str)  //将字符串转换为[]byte类型切片
b :=[]rune(str)  //将字符串转换为[]rune类型切片

map

Go内置字典类型叫map。map类型格式是:map[K]T,其中K是任意可以进行比较的类型,T是值类型。map也是一种饮用类型。
  • map的创建
    使用字面量创建。例如:
	ma := map[string]int{"a": 1, "b": 2}
	fmt.Println(ma["a"])
	fmt.Println(ma["b"])

使用内置的make函数创建。例如:

make(map[K]T) //map的容量使用默认值
make(map[K]T, len)  //map的容量使用给定的len值
mp1 :=make(map[int]string)
mp2 :=make(map[int]string, 10)
mp1[1] = "tom"
mp2[1] = "pony"
fmt.Println(mp1[1])  //tom
fmt.Println(mp1[2]) //pony
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值