600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > go语言的数据类型

go语言的数据类型

时间:2020-10-05 01:13:26

相关推荐

go语言的数据类型

值类型和引用类型

值类型

int、float、bool、string、数组、结构体

变量直接存储值,内存通常在栈中分配

引用类型

指针、slice切片、map、管道chan、interface

变量存储的是一个地址,这个地址对应的空间才是真正的存储数据(值),内存通常是在堆中分配的,没有任何变量引用这个地址时,改地址对应的数据空间就成为了一个垃圾,由GC来回收。

基本数据类型:

在Go中数据类型都有一个默认值,没有赋值时就会保留默认值,也叫零值。

数值型

Golang程序中整数类型变量在使用时,遵守保小不保大的原则,即在保证程序正确运行的情况下,尽量使用占用空间小的数据类型

整数类型:

有符号整数

无符号整数

package mainimport ("fmt""unsafe") func main(){var n int = 10//unsafe.Sizeof(n) 可以返回变量占用的字节数fmt.Printf("n 的类型 %T n占用的字节数是%d",n, unsafe.Sizeof(n))}

浮点类型:

可以用来表示小数

浮点数 = 符号位 + 指数位 + 尾数位

尾数位可能丢失造成精度损失


字符型

没有专门的字符型,使用byte来保存单个字母字符,由字符组成

注意:不能用byte存汉字,在go中采用utf-8的编码,一个汉字会占3个字节,可以用int32或者rune来储存

package mainimport ("fmt") func main(){//字符类型可以用来计算,相当于一个整数,数值为码值var n = 10 + 'a'fmt.Println(n) //107}


布尔型(bool)

只能取truefalse

占用一个字节

适用于逻辑运算


字符串(string)

是由固定长度的字符串联起来的字符序列,Go的字符是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。

使用形式:

1、双引号,会识别转义字符。

2、反引号,以字符串的原生形态输出保持换行和特殊字符,可以实现防止攻击。

注意:

1、字符串一旦赋值了,就不能修改了。

2、字符串拼接使用+


基本类型的类型转换

基本语法 T 将值v的类型转换为T

注意:

1、被转换的是变量存储的数据,变量本身的数据类型没有变化。

2、在转换中,比如int64转成int8,编译时不会报错,只是转换的结果会按溢出处理,和我们希望的结果不一样。

package mainimport ("fmt""unsafe") func main(){var i int = 1var j float32 = float32(i)fmt.Printf("i 的类型 %T n占用的字节数是%d \n" ,i, unsafe.Sizeof(i))fmt.Printf("j 的类型 %T n占用的字节数是%d \n" ,j, unsafe.Sizeof(j))}


派生/复杂数据类型:


指针(Pointer)

指针变量存的是一个地址,这个地址指向的内存空间才是值

值类型都有对应的指针类型,形式为*指针类型

值类型包括:int 、float 、 bool、string、数组、结构体

package mainimport ("fmt") func main(){var a int = 1fmt.Printf("a的地址%v\n",&a)var b *int = &afmt.Printf("b的值%v\n",b)fmt.Printf("b的地址%v\n",&b)fmt.Printf("b指向的值%v\n",*b)}

利用指针改变值

package mainimport ("fmt") func main(){var a int = 1var b *int = &a*b = 2fmt.Printf("a的值%v",a)}


数组

基本用法

语法var variable_name [SIZE] variable_type

package mainimport ("fmt") func main(){arr := [6] int {1,2,3,4,5,6} //int 占8字节fmt.Printf("arr的地址是%p \n", &arr) fmt.Printf("arr[0]的地址是%p \n", &arr[0]) //数组中第一个元素的地址和数组变量的地址是一样的fmt.Printf("arr[1]的地址是%p \n", &arr[1]) //后面元素的地址就是在数组地址基础上加上占用字节数// arr的地址是0xc00000a300 // arr[0]的地址是0xc00000a300 // arr[1]的地址是0xc00000a308}

如果数组长度不确定,可以使用 … 代替数组的长度,编译器会根据元素个数自行推断数组的长度:

var arr = [...]float32{1,2,3,4,5,6}

如果设置了数组的长度,我们还可以通过指定下标来初始化元素:

arr := [5]float32{1:2.0,3:7.0}

注意事项

1、一旦声明,其长度就不能改变

2、数组创建后,如果没有赋值,有默认值(零值):

int–> 0

bool–>false

string–> “”

3、数组中的元素可以是任意类型


结构体(struct)


管道(Channel)


函数

为完成某一功能的程序指令(语句)的集合,称为函数。

函数执行时会在内存中开辟一个执行空间,函数执行完毕该空间释放。

在Go中,函数分为:自定义函数、系统函数。

Go函数支持多个返回值。

func 函数名(形参列表)(返回值类型列表){执行语句...return 返回值列表}

函数的命名

1、函数的命名遵循标识符命名规格,首字母不能是数字

2、首字母大写的函数可以被本包和其他包文件使用,类似public

3、首字母小写只能被本包使用,其他包不能使用,类似于private

基本数据类型和数组默认都是值传递的,即进行值拷贝。在函数内部修改,不会影响到原来的值。

如果希望函数内的变量能影响到函数外的变量,可以传入变量的地址&,函数内衣指针的方式操作变量。

package mainimport ("fmt") func test1( n int) {n++fmt.Printf("test1 a= %v\n",n)}func test2( n *int ) {*n++fmt.Printf("test2 b=%v\n",*n)}func main(){a:=1b:= 1test1(a)test2(&b)fmt.Printf("a=%v\nb=%v\n",a,b)}

在go中函数也是一种数据类型。

package mainimport ("fmt") func getSum( n1 int, n2 int) int {return n1 + n2}//函数是一种数据类型,因此可以作为形参,并且调用func sumFun(funvar func(int, int) int, num1 int, num2 int ) int {return funvar(num1,num2)}func main(){//可以复制给一个变量,该变量就是一个函数类型的变量了,通过该变量可以对函数调用。a:= getSumres1 := a(1,2)res2 := sumFun(a,3,4)fmt.Printf("res1 = %v \n res2 =%v \n",res1,res2)}

支持返回值命名

package mainimport ("fmt") func myfun(n1 int, n2 int) (sum int , sub int) {//sum,sub为默认返回值已声明,可以直接赋值sum = n1 + n2sub = n1 - n2return}func main(){a, b := myfun(20,10)c, _ := myfun(30, 40) // _代表占位符fmt.Printf("a = %v \nb =%v \nc =%v \n",a,b,c)}

支持可变参数

通过args[index]获取参数

//支持0到多个参数func myfun(args...int) int{}//支持1到多个参数func myfun(n int,args...int) int{}

匿名函数

1、在定义匿名函数时直接调用,这种方式匿名函数只能调用一次

func main(){res := func (n1 int,n2 int) int {return n1 + n2}(1,2)fmt.Println("a=",res)}

2、将定义的匿名函数赋值给变量、这种方式可以多次调用

func main(){a := func (n1 int,n2 int) int {return n1 + n2}res := a(1,2)fmt.Println("res=",res)}

闭包

闭包就是一个函数和其他相关的引用环境组合的一个整体

package mainimport ("fmt") func add() func (int) int {n := 10return func (x int) int {return n + x}}func main(){f := add()res1 := f(2)res2 := f(3)fmt.Println("res=",res1,res2)}

defer

特性

关键字 defer 用于注册延迟调用。这些调用直到 return 前才被执。因此,可以用来做资源清理。多个defer语句,按先进后出的方式执行。defer语句中的变量,在defer声明时就决定了。

用途

关闭文件句柄锁资源释放数据库连接释放

当go执行到defer时,不会立即执行defer后的语句,而是将defer后的语句亚茹到一个栈中,然后执行下一语句,在函数执行完之后,再从栈中执行语句(先入后执行)

package mainimport ("fmt") func sum(n1 int, n2 int) int {//defer入栈时会拷贝相应的值defer fmt.Println("n1=",n1) //n1=10defer fmt.Println("n2=",n2) //n2=20n1++n2++res := n1 + n2defer fmt.Println("res=",res) //res=32return res}func main(){num := sum(10,20)fmt.Println("num=",num) //num=32}


切片(slice)


接口(interface)


map


自定义数据类型

基本语法: type 自定义数据类型名 数据类型

package mainimport ("fmt") func main(){//给int取了别名,在go中 myint 和 int 都是int类型,但是go认为他们是两个类型type myint intvar num1 myintvar num2 intnum1 = 40num2 = num1 //cannot use num1 (type myint) as type int in assignmentfmt.Printf("num1 = %v \num2 =%v \n",res1,res2)}

type myFunType func(int,int) int//函数是一种数据类型,因此可以作为形参,并且调用func sumFun(funvar myFunType, num1 int, num2 int ) int {return funvar(num1,num2)}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。