golang的复合类型

golang的复合数据类型:数组、slice、map、结构体。数组和结构体是聚合类型。它们的值由内存中的一组变量构成。数组元素具有相同的类型,而结构体可以不同。数组和结构体的长度都是固定的。slice和map是动态数据结构。

数组

var a [3]intname [nums]type

for i,j in := range a {
	fmt.printf("%d %d\n",i j)
}

r := [...]int{99 :-1}
数组长度位置出现省略号表示由初始化元素个数来确定长度。
数组长度是类型的一部分(不同长度类型不同编译会发生报错),数组长度必须是常量表达式。
如果一个数组元素类型可以比较,那数组之间可以比较。
使用数组指针是高效的。

slice

一个拥有相同类型元素的可变长序列。通常写作[ ]T。它看上去像没有长度的数组类型。切片是一个很小的对象,对底层数组 进行了抽象。
轻量级数据结构,可以用来访问数组部分或全部元素,而这个数组称为slice的底层数组。
slice三个特性:长度 容量 指针。指针指向数组的第一个可访问的元素。
因为slice包含了指向数组的指针,所以将一个slice传递给函数的时候,可以在函数内部修改底层数组的元素。
创建和初始化:make([]type,len,cap)。如果只有len,则len=cap。
另一种是切片字面量声明:slice := [ ]string{"1","2","3"}
切片也可以像数组一样使用索引声明slice := []int{99 :-1}

空切片和nil切片

声明后不作任何初始化,就是一个nil切片。var slice []int 指针为nil,len和cap都是0。
空切片 make创建或直接声明。具有指针地址。

多个切片共享一个数组。如果一个切片修改了底层数组的共享部分,另外的切片也会感知到。

切片使用append函数增加元素

append(slice,vaule),一个切片和被追加的值。长度改变容量可能会改变(取决于可用容量cap)。如果切片的底层数组容量也不够,将被引用的现在所有的值复制到新数组里,再追加新的值。

slice :=[]int{10,20,30,40} //len=cap=4
append(slice, 50)
//需要复制所有的值到新数组 len=4 cap=4*2

append扩展容量的算法:cap<1000成倍增加,大于1000,1.25倍增加。

创建切片时可以使用三个索引:slice := source[i:j:k]

source :=[]string{"a","b","c","d","e"}
slice := source[2:3:4]

slice从第三个元素开始切,长度为1,左闭右开,4为slice切片的终点。所以长度=j-i cap=k-i。
最后的索引不能越界(底层数组的容量)否则发生报错。

限制slice容量=长度的好处。当新切片第一次调用append时会创建一个新的数组,这个数组包括切片切的元素加追加的元素。,复制切片的元素再追加新元素,并返回一个引用了这个新底层数组的新切片。

package main

import "fmt"

func main() {

	slice1 := []int{1, 2, 3, 4, 5}
	slice2 := slice1[2:3]

	slice2 = append(slice2, 6)

	fmt.Printf("%v", slice1)
	fmt.Printf("%v", slice2)

}

运行结果:
在这里插入图片描述

切片中追加切片:使用…运算符
append(slice1,slice2… )

迭代切片

slice :=[]int{1,2,3,4,5}
for index,value range slice{
	fmt.Printf("%d %d",index ,value)
]

第一个元素是索引,第二个元素是值的副本。要注意的是副本值的地址为同一变量的地址。如果不需要索引值可以通过_占位符;来替代。也可以传统for i ;i<len(slice);i++{}来迭代。
切片在函数间传递开销很小。

映射内部实现和基础功能 map

映射是一个集合,可以使用类似处理数组和切片的方式迭代映射中的元素。但映射是无序的集合,原理是使用了散列表。
初始化:

dict = make(map([string]int))
dict :=map[string]string{"red":"qwe","yellow":"asdasd","green":"gbfdgh"}

创建的时候,键可以试任何值。内置类型或结构类型,只要这个值可以使用==做比较。
map用delete(name,key)删除。map可在函数建传递映射。

结构体

编译语言意味着,编译器需要在编译时知晓程序里每个值的类型。
值的类型给编译器提供两部分信息:分配多少内存给这个值;第二部分这段内存表示什么?

用户定义的类型

Golang允许用户定义类型。声明时,编译器会给这个新类型一个框架,告知必要的内存大小和表示信息。go中用户定义的类型方法有两种。最常用的事struct。

//声明一个结构体
type user struct{
	name 		string
	email 		string
	ext			int
	privileged 	bool

}

声明之后,就可以使用这个类型创建值了。

var bill user //被初始化为零值(根据其内置类型)

结构体也可以字面量初始化。初始化声明时,字段顺序要保持一致。也可以使用其他结构类型声明字段

type admin struct {
	person user
	level string

}


fred := admin {
	type user struct{
		name:			"lisa",
		email:			"@qq.com",
		ext:			213,
		privileged: 	true

	},
	level: "super"
}

基于内置类型的新类型

 type Duration int64

但是并不能用int64类型的值赋给Duration 类型的变量,这两个是不同类型的,尽管新类型Duration 的基础类型是int64。

方法

方法能给用户定义的类型增加新的行为。方法实际上是函数,只是在声明时,在关键字func和方法名之间增加一个参数。
分为值接受和指针接受。

func (u user)notify(){

	fmt.Printf("Sending User Email to %s<%s>\n",
				u.name
				u.eamil			)
	

}


类型的本质

声明一个新类型之后,声明一个该类型的方法之前,要弄清:这个类型的本质是什么?弄清之后,根据自己的需求,我们要做值传递还是指针传递。传递的一致性很重要。

内置类型

数值、布尔、字符串。当值传递给方法或函数时,应该传递一个对应值的副本。如果你对这些值增删时。

引用类型

切片、通道、映射、接口、函数类型。当声明引用类型变量时,创建的变量被称作标头(header)值。它是一个包含一个指向底层数据结构的指针。每个引用类型还包含一组独特的字段,用于管理底层数据结构。

结构类型

结构类型可以用来描述一组数据值,这组值的本质即可以是原始的,也可以是非原始的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值