-
博文分类专栏
- Jquery基础教程
-
- 文章:(15)篇
- 阅读:46583
- shell命令
-
- 文章:(42)篇
- 阅读:154304
- Git教程
-
- 文章:(36)篇
- 阅读:234924
- leetCode刷题
-
- 文章:(76)篇
- 阅读:131950
-
go语言的内置类型和内置函数以及自定义类型2018-03-18 13:58 阅读(5525) 评论(0)
一、内置类型
在上一篇文章里,简单介绍了Go语言中基础的数据类型,本文主要是汇总一下,go语言内置的数据类型,同时侧重介绍一下go语言的复合类型。
数据类型 类型关键字 布尔类型 bool 整型 int8、byte、int16、int、uint、uintptr等 浮动型 float32、float64 复数类型 complex64、complex128 字符 rune 字符串 string 错误类型 error 指针 pointer 数组 array 切片 slice 字典 map 通道 chan 结构体 struct 接口 interface 1、指针类型
指针类型,也叫做引用类型,在使用之前,必须初始化,即申明空间。可以通过new函数和make函数来初始化,也可以将其指向对应类型的变量。如下:
通过new来初始化
var sum *int sum = new(int)
通过指向指针对应类型的变量来初始化
var sum *int var sum1 int = 16 sum = &sum1 //这样sum指针里面存储的值是sum1的地址 *sum += 1 //改变sum对应的值,也就改变了sum1
2、数组
数组内存分配是连续的,所以迭代数组也是比较快的。
在数组的申明时候,我们需要指定,数组的长度和数组存储的数据类型,申明格式如下:
var arrayName [n]type
数组申明后,默认的值是对应类型的零值。如下:
var arr [3]string
申明一个字符串数组,默认是都是空。
数组的赋值如下:
var arr [3]string arr = [3]string{"www", "findme", "wang"}
当然,在赋值的时候,我们也可以不指定长度
var arr [3]string arr = [...]string{"www", "findme", "wang"}
此外,我们也可以根据数组下标,只针对某些进行赋值,如下:
var arr [3]string arr = [3]string{1:"findme", 2:"wang"}
3、切片
由于数据长度是固定的,且传递参数的时候,是以值的形式传递,为了解决这些痛点,于是切片来了。
切片是一种,可变的数组,有长度、容量以及指向的数组三个属性,在不增长的情况下,其长度不能超过其容量。
因为切片底层实现,就是数组,所以其切片的容量不能超过其底层数组的长度。
申明切片方式如下:
var arrayName []type
与申明数组的区别是,它不需要指定长度。
申明切片以后,并不能直接像数组一下,拿来直接使用,否则将会报错,如下:
var sli []string arr[0] ="nihao"
报错:panic: runtime error: index out of range
主要是因为切片,底层是数组,
切片可以通过make函数,或是基于已有的数组或切片方式来完成初始化,如下:
通过make函数初始化切片,格式如下:
make(t , len , capacity)
t代表切片类型;len代表切片的长度; capacity代表切片的容量,可选,默认值和len一样。
如下,申明一个长度和容量为5的切片
var sli []string sli = make([]string, 5)
通过数组初始化切片,格式如下:
sli = arr[i:j:k]//arr为数组,sli为切片,数组和切片对应的数据类型必须相同
i,j为数组中下标且j大于i,k用来控制切片的容量。
切片sli的长度为 j-i
当没有指定k时,切片sli的容量为len(arr) -i;当指定k值,容量为k-i
当然有一些简写的格式如下:
arrMaxIndex := len(arr) -1 sli = arr[1:] //等同于 arr[1:arrMaxIndex] sli = arr[:2] //等同于 arr[0:2] sli = arr[:] //等同于 arr[0:arrMaxIndex]
通过数组初始化切片案例如下:
var arr = [3]string{"你好", "我们", "在哪"} var sli []string sli = arr[1:2]//以arr数组创建切片,那么sli底层的数组就是arr sli[0] ="niaho" //当改变切片对应的值,数组的值也会发生变化
通过切片初始化切片,和数组来初始化切片的格式是一样的。案例如下:
var arr = [3]string{"你好", "我们", "在哪"} var sli []string sli = arr[:] sli2 := sli[1:2] //基于切片来创建切片 sli2[0] ="niaho" fmt.Println(arr) fmt.Println(sli) arr[2] ="我去" fmt.Println(sli) fmt.Println(sli2)
sli和sli2,底层数组都指向了arr,当他们三个,任意的一个值发送了变化,其他的也对应着变动。上面输出结果为:
通过切片初始化,也可直接使用如下格式:
var sli []string sli = []string{"你好", "我们", "在哪"}
在go语言中,如果切片的长度不够用,是可以增加的,通过go语言内置的append函数来增加其长度。append函数的描述如下:
// The append built-in function appends elements to the end of a slice. If // it has sufficient capacity, the destination is resliced to accommodate the // new elements. If it does not, a new underlying array will be allocated. // Append returns the updated slice. It is therefore necessary to store the // result of append, often in the variable holding the slice itself: // slice = append(slice, elem1, elem2) // slice = append(slice, anotherSlice...) // As a special case, it is legal to append a string to a byte slice, like this: // slice = append([]byte("hello "), "world"...) func append(slice []Type, elems ...Type) []Type
说明,在使用append函数时候,会返回一个新的切片,新切片长度一定会比原切片大,容量不一定会变,主要取决于切片的可用容量。
如果切片的容量够用,则append函数,返回的新切片和原切片的底层数组相同。
如果切片的容量不够,则append函数,返回的新切片和原切片的底层数组不相同。也就是说append会创建一个新的底层数组,并将现有的值复制到新的底层数组中,让新的切片使用。在创建底层数组时,其长度的规则:如果切片容量小于1000,底层数组的长度会成倍的增加,一旦超过1000,容量的增长因子是1.25。
案例如下:
var arr = [3]string{"你好", "我们", "在哪"} var sli []string sli = arr[1:2:2]// 以arr创建切片,长度为1,容量也为1 sli[0] = "findme" //改变sli对应的值,会影响到arr fmt.Println(arr) fmt.Println(sli) sli = append(sli, "在家") //增加切片长度,由于容量不够用,会新建底层数组 sli[0] = "wang" //改变sli对应的值,不会影响到arr,因为sli底层数组已经不是arr了 fmt.Println(arr) fmt.Println(sli) //输出 [你好 findme 在哪] [findme] [你好 findme 在哪] [wang 在家]
所以,当我们创建切片的时候,若指定长度和容量一样的时候,一旦使用appen增加容量的时候,就会让创建新的切片底层数组和原切片的底层数组分离。
二、内置函数
函数 说明 append 把东西增加到slice里面,返回修改后的slice close 关闭channel delete 从map中删除key对应的value panic 终止程序继续往下执行,抛出一个异常 recover 读取panic抛出的异常 imag(c ComplexType) 返回复数对应的虚部 real(c ComplexType) 返回复数对应的实部 make 返回Type本身(只能应用于slice, map, channel) new 返回指向Type的指针 copy 复制slice,返回复制的数目 len 返回长度 三、自定义类型
在go里面,有两种方式,创建自定义类型,第一种使用结构体struct;第二种方式是通过type重定义某个类型。
比如重定义一个学生类型,如下:
type Student struct { Name string Age uint }
将上面的学生类型,定义为其他类型
type st Student
使用如下:
var s1 = st{"dqs", 18} fmt.Println(s1)