数据类型
整数
主要分两类int
和uint
。
int类型
有符号整数型。
int
类型
编译器自动推导默认的类型。你的程序在32位操作系统下运行就是int32
,你的程序在64位操作系统下运行就是int64
。所以在使用int
类型时不建议指定int32
或者int64
,需要考虑程序在不同操作系统下的兼容性。在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int
和uint
。- uint类型
uint
和int
的区别是一个带正负号±
一个不带±
号。 uintptr
类型
是无符号整数型,用于存放一个指针。
数字字面量语法(Number literals syntax)
二进制0b
开头,八进制0o
开头,十六进制0x
开头。下面a:=b
用占位符%v
显示ASCII码是98
,用占位符%q
显示字符是b
,用占位符%b
,显示二进制是1100010
。那么反过来一样的道理,b:=0b1100010
的话用占位符%q
打印出来就直接是字符b
了。综上所述:数字字面量语法可以让我们以二进制的方式定义数字。注意这里的变量b
的类型还是int
,也就是从根本上说变量b
还是一个int
类型的变量,保存的数据还是int
型的98
,只是用二进制的形式保存的int
型数字98
。如下列:
a := 'b' //变量'a'保存的数据是字符'b'
fmt.Println("变量'a'的值是字符'b'")
fmt.Printf("[%%v]默认格式:%v\n", a) // 用占位符'%v'显示ASCII码是字符'b'。
fmt.Printf("[%%q]字符格式:[%q]\n", a) // 用占位符'%q'显示字符是'98'。
fmt.Printf("[%%b]二进制:[%b]\n", a) // 用占位符'%b'显示二进制是'1100010'。
fmt.Println("----------------------------------------")
b := 0b1100010 // 反过来变量'b'保存的数据是二进制'1100010',也就是十进制的数字'98'。
fmt.Println("变量'b'的值是'0b001100010'")
fmt.Printf("[%%v]默认格式:%v\n", b)
fmt.Printf("[%%q]字符格式:[%q]\n", b) // 用占位符'%q'显示变量'b'就是字符'b'了。
fmt.Printf("[%%b]二进制:[%b]\n", b)
fmt.Printf("变量b的数据类型是:[%T]\n",b)// 用占位符'%T'显示变量'b'的数据类型还是'int'整数型。
另外还可以使用_
来分割数字。比如c:=123_456
等于123456
。另外,经测试f:=0b10
没问题,f:=0b10_11
输出十进制19
,f:=0b10_0b11
编译器报错,不能编译。个人猜测认为_
在go语言中不占用命名空间不分配地址,也就是说_
在存储的数据中基本相当于不存在的东西,但是还是能显示出来的。所以f:=0b10_11
相当于十进制19
,但是f:=0b10_0b11
相当于两个十进制的数字2
和3
,但是一个变量只能保存一个二进制数字,你让他保存俩二进制数字,又不让人家变数组,人家肯定不干啊。是吧,感觉这么理解问题不大。嘿嘿。(待续…)
浮点型
浮点型通俗说就是小数形式,比如3.1415
等。支持float32
和float64
这两种都遵循IEEE 745标准。默认float64
类型。float32
最大范围是3.4e38
。float64
最大范围1.8e308
。可以用占位符%f
打印float64
数据类型,我的arm64平台用占位符%f
输出小数点后6位。例如c:=3.1415926888
输出3.141593
,小数点后保留6位。如果细心一点你会发现就算保留小数点后六位也应该是3.141592
啊,这是因为2后边是8
,四舍五入就变成3.141593
喽。当然,你也可以把占位符改车%.2f
强制要求保留到小数点后两位,输出3.14
啊。要记住,第三位的四舍五入昂。
复数complex64和complex128
复数有实部和虚部,complex6
4的实部和虚部为32位,complex128
的实部和虚部为64位。(这个复数不知道干啥用的,现在也用不到,了解太少,以后在研究吧。)
布尔型bool
bool
布尔型只有两个值真true
和假false
,这个简单,容易理解。
字符串
Go语言字符串内部实现使用UTF-8
编码。字符串的值是双引号""
里面的内容。可以在Go源代码中直接添加非ASCII码
字符。
转义字符
Go语言中常年转义字符有:回车符\r
,换行符\n
,单引号'
,双引号""
和反斜杠\
。都是用反斜杠\
来转义。还有一个百分号%
在fmt.Printf
系列函数中有%
来转义,比如fmt.Printf("%%d")
输出的是%d
而不是做占位符来使用。
多行字符串
定义一个多行字符串要用单引号''
来包含。但是单引号内的所有字符都按照原样输出。所有转义字符均无效。
字符串常用到的操作:
- 求字符串长度。
求字符串长度用len(str)
- 拼接字符串
str3:=fmt.Sprintf("%s%s",str1,str2)
拼接字符串str1
和str2
用占位符%s
的形式拼接字符串str1
和str2
并赋值给变量str3
。记住,fmt.Sprint
拼接后的数据一定是string
类型。所以你也可以fmt.Sprint("%d%d",int1,int2)
把两个int
类型转变为string
类型。 - 分割字符串
strings.Split("待分割的字符串","分割符(可以是字符串)")
分割字符串,分割后是[]string
类型。 - 判断包含
strings.Contains('str1','str2')
判断字符串str1
中是否包含str2
。返回bool
型true
或者false
。 - 判断前缀
strings.HasPrefix('str1','s')
判断字符串在str1
是不是以s
开头,返回true
。strings.HasSuffixa('str1','str2')
判断后缀。 - 判断字符串出现的位置
strings.Index('str1','a')
判断字符串str1
中字符a
出现的位置返回-1
表示从来没有出现过。strings.LastIndex('str1str1','r')
判断字符串str1str1
中r
最后一次出现的位置返回6
。 - 拼接字符串
strings.Join('str[] string','-')
把字符串数组str[] string
用-
拼接起来。返回string
类型。
byte和rune字符类型
Go语言默认的字符类型是int32
,当然你也可以用byte()
强制定义为int8
,仅限于英文字母等255个ASCII码
,其它字符比如汉字字符等需要用rune()
来定义。因为最开始的255个ASCII码
用int8
可以表示,但是后面新增加的ASCII码
用一个字节int8
存储不下啊。所以需要用int32
来存储。
a := 's'
b := byte('s')
c := '我'
// d := byte('我') //'int8'的存储空间不够,需要用'rune()'定义为'int32'来存储。
e := rune('我')
fmt.Printf("a的类型:[%T] a的值:[%q]\n", a, a)
fmt.Printf("b的类型:[%T] b的值:[%q]\n", b, b)
fmt.Printf("c的类型:[%T] b的值:[%q]\n", c, c)
fmt.Printf("e的类型:[%T] b的值:[%q]\n", e, e)
所以遍历字符串时如果用len()
来获取中英混合字符串hello,铁柱和钢蛋
就会出现如下错误。
a := "he铁蛋a!"
for i := 0; i < len(a); i++ {
fmt.Printf("[%d] %q \n", i, a[i])
}
输出如下:
[0] 'h'
[1] 'e'
[2] 'é'
[3] '\u0093'
[4] '\u0081'
[5] 'è'
[6] '\u009b'
[7] '\u008b'
[8] 'a'
[9] '!'
所以遍历不确定字符串是强烈建议使用range s
来获取字符串长度。如下代码正常输出没有错误。
a := "he铁蛋a!"
for i,r:=range a {
fmt.Printf("[%d] %q \n", i,r)
}
输出如下:
[0] 'h'
[1] 'e'
[2] '铁'
[5] '蛋'
[8] 'a'
[9] '!'
修改字符串
Go语言不能直接修改字符串。如果确定需要修改字符串,必须先把字符[]byte()
或者[]rune()
转换成字符切片,修改完成后在转换为string
类型。
a := "he铁蛋a!" //声明并初始化变量'a'
fmt.Printf("%v \n", a) //打印变量'a'
b := []rune(a) //转换变量'a'为切片并赋值给切片'b'
fmt.Printf("%q \n", b) //打印切片'b'
b[1] = '钢' //修改切片'b'
fmt.Printf("%q \n", b) //打印切片'b'
fmt.Printf("%v", a) //打印字符串'a'
a = string(b) //把切片'b'转换为字符串类型并赋值给字符串'a'
fmt.Printf("%v", a) //打印字符串'a'
类型转换
一个变量定义好了类型就不能在改变了。比如a:=98
,这个a
永远就是int
类型,而且根据你的系统平台只能是int64
或者int32
类型,哪怕你把他变成int8
都不行,他永远就是int64
。改变变量值的类型的办法也就,就是比较麻烦。先定义一个float64
类型的变量b
,在把变量a
的值float64(a)
转换成float64
类型在赋值给变量b
即可。注意,int
类型可以转换为float
型,但是float
型不能通过这种办法转换成int
类型,因为会丢失精度。另外,int
类型变字符串也很麻烦。看下面代码:
a := 90
var b string
b = string(a)
fmt.Printf("%v", b)
原本我以为打印steing
类型的变量b
会输出90
,结果打脸啊,想的太简单了。b=string(a)
是把a
的值98
当做一个数字赋值给string
型的b
,相当于b
接收到的是ASCII码90
所以输出Z
。看来要把int
转换成string
类型还要对int
求余,切片,在转换为string
才行。float
类型同样道理啊。这个以后有时间在研究吧。(待续)。