Golang语言学习笔记(二)
Golang数据类型介绍
Go语言中数据类型分为:基本数据类型和复合数据类型
基本数据类型有:整形,浮点型,布尔型,字符串
复合数据类型有:数组,切片,结构体,函数,map,通道(channel),接口等。
一、基本数据类型
1.整形
整形分为以下两个大类:
有符号整形按长度分为:int8,int16,int32,int64
对应的无符号整形:uint8,uint16,uint32,uint64
类型 | 范围 | 占用空间 | 有无符号 |
---|---|---|---|
int8 | (-128到127) -27</sup>到2<sup>7 -1 | 1个字节 | 有 |
int16 | (-32768到32767) -215</sup>到2<sup>15 -1 | 2个字节 | 有 |
int32 | (-2147483648到2147483647) -231</sup>到2<sup>31 -1 | 4个字节 | 有 |
int64 | (-9223372036854775805到9223372036854775807) -263</sup>到2<sup>63 -1 | 8个字节 | 有 |
uint8 | (0到255) 0到2^8 -1 | 1个字节 | 无 |
uint16 | (0到65535) 0到2^16 -1 | 2个字节 | 无 |
uint32 | (0到4294967295) 0到2^32 -1 | 4个字节 | 无 |
uint64 | (0到18446744073709551615) 0到2^64 -1 | 8个字节 | 无 |
代码:
Demo04\main.go
package main
import (
"fmt"
// "unsafe"
)
func main(){
//1.定义int类型
// var num int = 10
// num = "aa"//赋值时不能将其他类型的值赋给当前变量,否则会报错cannot use "aa" (type untyped string) as type int in assignment
// num = 22.22//constant 22.22 truncated to integer
// fmt.Printf("num=%v, 类型为:%T",num,num)
//2.int8的范围演示
// var num int8 = 98
// fmt.Printf("num=%v, 类型为:%T",num,num)//num=98, 类型为:int8
// var num int8 = 130 (-128到127)
// fmt.Printf("num=%v, 类型为:%T",num,num)//constant 130 overflows int8
// var num int16 = 130
// fmt.Printf("num=%v, 类型为:%T",num,num)//num=130, 类型为:int16
//3.uint的范围(0-255)
// var a uint8 = 255
// fmt.Printf("a=%v, a的类型是%T",a,a)//a=255, a的类型是uint8
// var a uint8 = -2
// fmt.Println(a)//-2超出了uint8的范围,编译时报错:constant -2 overflows uint8
//4.int8 int16 ...占用的存储空间大小
// unsafe.Sizeof查看不同长度的类型 在内存里面的存储空间
// var a int8 = 15
// fmt.Printf("num=%v, 类型为:%T\n",a,a)
// fmt.Println(unsafe.Sizeof(a))//1字节
// var b int64 = 15
// fmt.Printf("num=%v, 类型为:%T\n",b,b)
// fmt.Println(unsafe.Sizeof(b))//8字节
//5.int不同长度之间的转换
// var a1 int32 = 10
// var a2 int64 = 21
// fmt.Println(a1+ a2)//invalid operation: a1 + a2 (mismatched types int32 and int64)
// fmt.Println(int64(a1)+ a2)//31,把a1转换成64位
// fmt.Println(a1+ int32(a2))//31,把a2转换成32位
//高位向地位转换的时候要注意
// var n1 int16 = 130
// fmt.Println(int8(n1))//-126,溢出,有问题
// var n2 int16 = 110
// fmt.Println(int8(n2))//110,没有问题
// var n3 int16 = 110
// fmt.Println(int64(n3))//110
//6.int数字字面量语法 %d表示10进制输出,%b表示二进制输出, %o表示八进制输出, %x表示十六进制输出
// num := 30
// fmt.Printf("num=%v,类型:%T\n",num,num)//num=30,类型:int,Go中的int在不同位数的操作系统上表示的位数也不一样,32位的系统上就表示int32,64位的系统上就表示int64
// fmt.Println(unsafe.Sizeof(num))//8,表示64位的计算机,int就是int64, 占用8个字节
// var test int = 9223372036854775807
// fmt.Println(test)//9223372036854775807,当前操作系统是64位,可接收int64取值范围内的最大值9223372036854775807
num := 9
fmt.Printf("num=%v\n", num)//num=9,%v 表示原样输出
fmt.Printf("num=%d\n", num)//num=9,%d 表示10进制输出
fmt.Printf("num=%b\n", num)//num=1001,%b 表示二进制样输出
fmt.Printf("num=%o\n", num)//num=11,%o 表示八进制输出
fmt.Printf("num=%x\n", num)//num=9,%x 表示十六进制输出
}
2.浮点数
Go语言支持两种浮点数类型:float32和float64
float32的浮点数的最大范围约为3.4e38,可以使用常量定义:math.MaxFloat32
float64的浮点数的最大范围约为1.8e308,可以使用一个常量定义:math.MaxFloat64
打印浮点数时,可以使用fmt包配合动词%f
代码:
Demo05/main.go
package main
import (
"fmt"
// "unsafe"
// "github.com/shopspring/decimal"
)
func main(){
//定义float类型
// var a float32 = 3.12
// fmt.Printf("a=%v--%f,类型:%T\n",a,a,a)//a=3.12--3.120000,类型:float32,使用%f默认保留小数点后六位
// fmt.Println(unsafe.Sizeof(a))//float32占用4个字节
// var b float64 = 3.12
// fmt.Printf("b=%v--%f,类型:%T\n",b,b,b)//b=3.12--3.120000,类型:float64,使用%f默认保留小数点后六位
// fmt.Println(unsafe.Sizeof(b))//float64占用8个字节
//2.%f 输出float类型 %.2f输出数据的时候保留2位小数
// var c float64 = 3.1415926
// fmt.Printf("%v--%f--%.2f",c,c,c)//3.1415926--3.141593--3.14
//保留4位小数
// var d float64 = 3.1415926
// fmt.Printf("%.4f",d)//3.1416
//3. 64位的系统中,Go语言中浮点数默认是float64
// f1 :=3.1415656456
// fmt.Printf("%f--%T",f1,f1)//3.141566--float64
//4. Golang 科学计数法表示浮点类型
// var f2 float32 = 3.14e2 //表示f2等于3.14*10的2次方
// fmt.Printf("%v--%T",f2,f2)//314--float32
// var f3 float32 = 3.14e-2 //表示f2等于3.14除以10的2次方
// fmt.Printf("%v--%T",f3,f3)//0.0314--float32
//5.Golang中float精度丢失问题
// var f4 float64 = 1129.6
// fmt.Println(f4 * 100)//112959.99999999999
// m1 := 8.2
// m2 := 3.8
// fmt.Println(m1 - m2)//期望是4.4,结果打印出:4.3999999999999995
//解决精度问题,引入第三方包,decimal
//加法
// var num1 float64 = 3.1
// var num2 float64 = 4.2
// d1 := decimal.NewFromFloat(num1).Add(decimal.NewFromFloat(num2))
// fmt.Println(d1)//7.3
//减法 Sub,乘法 Mul,除法 Div 用法均与上述类似
//6.int类型转换成float类型
// a :=10
// b := float64(a)
// fmt.Printf("a的类型是%T,b的类型是%T",a,b)//a的类型是int,b的类型是float64
//7.float类型与float类型的转换
// var a1 float32 = 23.4
// a2 := float64(a1)
// fmt.Printf("a1的类型是%T,a2的类型是%T",a1,a2)//a1的类型是float32,a2的类型是float64
//8.float类型转int类型(不建议这样做)
var c1 float32 = 23.45
c2 := int(c1)
fmt.Printf("c2的值:%v,c2的类型%T",c2,c2)//c2的值:23,c2的类型int
}
3.布尔型
Go语言中以bool类型进行声明布尔类型数据,布尔型数据只有true(真)和false(假)两个值。
注意:
1.布尔类型变量的默认值为false
2.Go语言中不允许将整形强制转换为布尔型
3.布尔型无法参与数值运算,也无法与其他类型进行转换。
代码
Demo06/main.go
package main
import (
"fmt"
)
func main(){
// var flag bool = true
// fmt.Printf("%v-%T",flag,flag)//true-bool
//1.布尔类型变量的默认值为false
// var b bool
// fmt.Printf("%v",b)//false
//2.string型变量的默认值为空
// var s string
// fmt.Printf("%v",s)
//3.int型变量的默认值为0
// var i int
// fmt.Printf("%v",i)//0
//4.float类型变量的默认值为0
// var f float32
// fmt.Printf("%v",f)//0
//5.Go语言中不允许将整形强制转换为布尔型
// var a = 1
// if a {//错误写法:non-bool a (type int) used as if condition
// fmt.Printf("true")
// }
//6.布尔型无法参与数值运算,也无法与其他类型进行转换
// var s = "this is error"
// if s{//错误写法:non-bool s (type string) used as if condition
// fmt.Printf("true")
// }
var f1 = false
if f1{
fmt.Printf("true")
}else{
fmt.Printf("false")//false
}
}
4.字符串
Go语言中的字符串一原生数据类型出现,使用该字符串就像使用其他原生数据类型(int,bool,float32,float64等)一样。Go语言里的字符串的内部实现使用UTF-8编码。字符串的值为双引号("")中的内容,可以在Go语言的源码中直接添加非ASCII码字符。
字符串转义符
Go语言的字符串常见转义符包含回车,换行,单双引号,制表符等,如下表所示
转义符 | 含义 |
---|---|
\r | 回车符(返回首行) |
\n | 换行符(直接跳到下一行的同列位置) |
\t | 制表符 |
\' | 单引号 |
\" | 双引号 |
\|反斜杠 |
字符串的常用操作
方法 | 介绍 |
---|---|
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex | 子串出现的位置 |
strings.Join(a[]string,sep string) | join操作 |
byte和rune类型(了解)
组成每个字符串的元素叫做“字符”,可以通过遍历字符串元素获得字符。字符用单引号(’‘)包裹起来
Go语言的字符有以下两种
1.uint8类型,或者叫byte型,代表了ASCII码的一个字符
2.rune类型,代表一个UTF-8字符(当需要处理中文,日文或者其他复合字符时,则需要用到rune类型。rune类型实际是一个int32)
代码:
Demo01/main.go
package main
import (
"fmt"
// "strings"
)
func main(){
//1.定义string类型
// var str1 string = "你好Golang"
// var str2 = "你好 Go"
// str3 := "Hello Golang"
// fmt.Printf("str1=%v---类型:%T\n",str1,str1)//str1=你好Golang---类型:string
// fmt.Printf("str2=%v---类型:%T\n",str2,str2)//str2=你好 Go---类型:string
// fmt.Printf("str3=%v---类型:%T\n",str3,str3)//str3=Hello Golang---类型:string
//2.字符串转义符
// str1 := "this is str"
// fmt.Println(str1)//this is str
// str2 := "this \nis str"
// fmt.Println(str2)
/*
this
is str
*/
// str3 := "C:\Go\bin"//想要输出C:\Go\bin,编译时: unknown escape
// fmt.Println(str3)
// str4 := "C:\\Go\\bin"//想要输出C:\Go\bin,使用\转义
// fmt.Println(str4)//C:\Go\bin
//3.多行字符串 `(反引号) tab键上面,原样输出
// str := `this is first line
// this is second line
// this is third line
// `
// fmt.Println(str)
//4.len(str)求长度
// var str1 = "你好"
// fmt.Println(len(str1))//6,一个汉字占用三个字节
// var str2 = "aaaa"
// fmt.Println(len(str2))//4
//5.+或者fmt.Sprintf拼接字符串
// str1 := "你好"
// str2 := "Golang"
// str3 := str1 + str2
// str4 := fmt.Sprintf("%v %v",str1,str2)
// fmt.Println(str3)//你好Golang
// fmt.Println(str4)//你好 Golang
// str1 := "Go语言的字符串常见转义符包含回车," +
// "换行,单双引号,制表符等," +
// "如下表所示"
// fmt.Println(str1)
//6.strings.Split 分割字符串 strings需要引入strings包
// var str = "123-456-789"
// arr := strings.Split(str,"-")
// fmt.Println(arr)//[123 456 789] 切片 (简单的理解切片就是数组 在golang中切片和素组还有一切区别)
//7.strings.Join(a[]string,sep string) join 操作 表示把切片连接成字符串
// var str = "123-456-789"
// arr := strings.Split(str,"-")
// str2 := strings.Join(arr,"*")
// fmt.Println(str2)//123*456*789
// arr :=[]string{"php","java","golang"} //切片
// str3 := strings.Join(arr,"-")
// // fmt.Println(str3)//php-java-golang
// fmt.Printf("%v--%T",str3,str3)//php-java-golang--string
//8.strings.Contains 判断是否包含
// str1 := "this is str1"
// str2 := "this"
// str3 := "thisxxx"
// flag1 := strings.Contains(str1,str2)
// flag2 := strings.Contains(str1,str3)
// fmt.Println(flag1)//true
// fmt.Println(flag2)//false
//9.strings.HasPrefix,strings.HasSuffix 前缀/后缀判断
// str1 := "this is str"
// str2 := "this"
// str3 := "str"
// flag1 := strings.HasPrefix(str1,str2)
// flag2 := strings.HasSuffix(str1,str3)
// fmt.Println(flag1)//true
// fmt.Println(flag2)//true
//9.strings.Index(),strings.LastIndex() 字串出现的位置,查找不到返回-1,查找到返回下标位置,下标从0开始
// str1 := "this is str"
// str2 := "is"
// str3 := "xxx"
// num1 := strings.Index(str1,str2)
// fmt.Println(num1)//2
// num2 := strings.LastIndex(str1,str2)
// fmt.Println(num2)//5
// num3 := strings.LastIndex(str1,str3)
// fmt.Println(num3)//-1
//10.golang中定义字符
//1).字符属于int类型
// var a = 'a'
// fmt.Printf("值:%v, 类型:%T",a,a)//值:97, 类型:int32
//当直接输出byte(字符)的时候输出的时这个字符对应的码值
//2).原样输出字符
// var a = 'a'
// fmt.Printf("值:%c, 类型:%T",a,a)//值:a, 类型:int32
//3).定义一个字符串输出字符串里面的字符
// var str = "this"
// fmt.Printf("值:%v,原样输出:%c, 类型:%T",str[2],str[2],str[2])//值:105,原样输出:i, 类型:uint8
//4).一个汉字占用3个字节(golang中采用UTF-8编码),一个字母占用一个字节
// unsafe.Sizeof(str) 不能查看string类型数据所占的存储空间,用len来查看字符串类型数据所占的存储空间
// var str = "this" //占用4个字节
// fmt.Println(len(str))//4
// var str = "你好golang" //占用12个字节
// fmt.Println(len(str))//12
//5).定义一个字符 字符的值时汉字
//golang中汉字使用的时utf-8编码,编码后的值就是int类型
// var a = '国'
// fmt.Printf("值:%v,原样输出:%c, 类型:%T",a,a,a)//值:22269,原样输出:国, 类型:int32,Unicode编码10进制
//6). 通过循环输出字符串里面的字符
// str := "你好 golang"
// for i := 0; i<len(str);i++ { //byte
// fmt.Printf("%v(%c) ",str[i],str[i])//228(ä) 189(½) 160( ) 229(å) 165(¥) 189(½) 32( ) 103(g) 111(o) 108(l) 97(a) 110(n) 103(g),字符串中有汉字,不能正常输出
// }
// for _, v :=range str{ //rune
// fmt.Printf("%v(%c) ",v,v)//20320(你) 22909(好) 32( ) 103(g) 111(o) 108(l) 97(a) 110(n) 103(g)
// }
//7).修改字符串,要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string,无论哪种转换,都会重新分配内存,并赋值字节数组
// s1 := "big"
// s1[0] = 'p'
// fmt.Println(s1)//cannot assign to s1[0]
// byteStr := []byte(s1)
// byteStr[0] = 'p'
// fmt.Println(string(byteStr))//pig,//强制类型转换
s2 :="你好Golang"
runeStr := []rune(s2)
runeStr[0] = '大'
fmt.Println(string(runeStr))//大好Golang
}
二、GoLang中基本数据类型之间的转换
1.数值类型之间的相互转换
数值类型包括:整型和浮点型
2.其他类型转换成String类型
1).sprintf 把其他类型转换成string类型
注意:sprintf使用中更需要注意转换的格式:int为%d,float为%f,bool为%t,byte为%c
2).使用strconv包里面的几种转换方法进行转换
3.String类型转换成数值类型
1).string类型转换成int类型
2).string类型转换成float类型
3).string类型转换成bool类型(意义不大)
4).string类型转换成字符类型
4.数值类型不能和bool类型进行转换
代码
Demo08/main.go
package main
import (
"fmt"
// "strconv"
)
func main(){
//1.整型和整型之间的转换
// var a int8 = 20
// var b int16 = 40
// // fmt.Println(a + b)//invalid operation: a + b (mismatched types int8 and int16)
// fmt.Println(int16(a) + b)//60
//2.浮点型和浮点型之间的转换
// var a float32 = 20
// var b float64 = 40
// // fmt.Println(a + b)//invalid operation: a + b (mismatched types float32 and float64)
// fmt.Println(float64(a) + b)//60
//3.整型和浮点型之间的转换
// var a float32 = 20.23
// var b int64 = 40
// // fmt.Println(a + b)//invalid operation: a + b (mismatched types float32 and int64)
// fmt.Println(a + float32(b))//60.23
//注意:转换的时候建议从低位转换成高位,高位转换成低位的时候如果转换不成功就会溢出,和预期结果不一致。
//4.其他类型转换成String类型
//1).使用sprintf 把其他类型转换成string类型
// var i int = 20
// var f float64 = 12.3456
// var t bool = true
// var b byte = 'a'
// str1 := fmt.Sprintf("%d",i)
// fmt.Printf("值:%v,类型%T",str1,str1)//:20,类型string
// str2 := fmt.Sprintf("%f",f)
// fmt.Printf("值:%v,类型%T",str2,str2)//值:12.345600,类型string
// str3 := fmt.Sprintf("%t",t)
// fmt.Printf("值:%v,类型%T",str3,str3)//值:true,类型string
// str4 := fmt.Sprintf("%c",b)
// fmt.Printf("值:%v,类型%T",str4,str4)//值:a,类型string
//2).使用strconv包里面的几种转换方法进行转换
/*
FormatInt
参数1:int64的数值
参数2:传入int类型的进制
*/
// var i int = 20
// str1 := strconv.FormatInt(int64(i),10)
// fmt.Printf("值:%v,类型%T",str1,str1)//值:20,类型string
/*
FormatFloat
参数1:要转换的flaot64的数值
参数2:格式化类型,常用:'f'(-ddd.dddd)
参数3:保留的小数点 -1(不对小数点格式化)
参数4:格式化的类型 传入64 32
*/
// var f float32 = 20.4567
// str2 := strconv.FormatFloat(float64(f),'f',2,64)
// fmt.Printf("值:%v,类型%T",str2,str2)//值:20.46,类型string
// str3 := strconv.FormatBool(true)//没有任何意义
// fmt.Printf("值:%v,类型%T",str3,str3)//值:true,类型string
// a := 'a'
// str4 := strconv.FormatUint(uint64(a),10)
// fmt.Printf("值:%v,类型%T",str4,str4)//值:97,类型string
//5.String类型转换成其他类型
//1).string类型转换成整型
// str := "123456"
// fmt.Printf("%v--%T\n",str,str)//123456--string
/*
ParseInft
参数1:string数据
参数2:进制
参数3:位数 16 32 64
*/
// num := strconv.ParseInt(str,10,64)//ParseInt返回两个值,第一个是num,第二个是error:assignment mismatch: 1 variable but strconv.ParseInt returns 2 values
// num, _ := strconv.ParseInt(str,10,64)
// fmt.Printf("%v--%T",num,num)//123456--int64
//2).string类型转换成浮点型
/*
ParseFloat
参数1:string数据
参数2:位数 32 64
*/
// str :="123456.77"
// num, _ := strconv.ParseFloat(str,64)
// fmt.Printf("%v--%T",num,num)//123456.77--float64
//3).string类型转换成bool型
// b,_ := strconv.ParseBool("true")
// fmt.Printf("%v--%T",b,b)//true--bool
//不建议把string类型转换成bool型
// b,_ := strconv.ParseBool("xxxxxx")
// fmt.Printf("%v--%T",b,b)//false--bool
//3).string类型转换成字符型
s := "你好Golang"
for _, r :=range s {//rune
fmt.Printf("%v(%c) ",r,r)//20320(你) 22909(好) 71(G) 111(o) 108(l) 97(a) 110(n) 103(g)
}
}