Go语言数据类型

数据类型

整数

主要分两类intuint

int类型

有符号整数型。

  • int类型
    编译器自动推导默认的类型。你的程序在32位操作系统下运行就是int32,你的程序在64位操作系统下运行就是int64。所以在使用int类型时不建议指定int32或者int64,需要考虑程序在不同操作系统下的兼容性。在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用intuint
  • uint类型
    uintint的区别是一个带正负号±一个不带±号。
  • 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输出十进制19f:=0b10_0b11编译器报错,不能编译。个人猜测认为_在go语言中不占用命名空间不分配地址,也就是说_在存储的数据中基本相当于不存在的东西,但是还是能显示出来的。所以f:=0b10_11相当于十进制19,但是f:=0b10_0b11相当于两个十进制的数字23,但是一个变量只能保存一个二进制数字,你让他保存俩二进制数字,又不让人家变数组,人家肯定不干啊。是吧,感觉这么理解问题不大。嘿嘿。(待续…)

浮点型

浮点型通俗说就是小数形式,比如3.1415等。支持float32float64这两种都遵循IEEE 745标准。默认float64类型。float32最大范围是3.4e38float64最大范围1.8e308。可以用占位符%f打印float64数据类型,我的arm64平台用占位符%f输出小数点后6位。例如c:=3.1415926888输出3.141593,小数点后保留6位。如果细心一点你会发现就算保留小数点后六位也应该是3.141592啊,这是因为2后边是8,四舍五入就变成3.141593喽。当然,你也可以把占位符改车%.2f强制要求保留到小数点后两位,输出3.14啊。要记住,第三位的四舍五入昂。

复数complex64和complex128

复数有实部和虚部,complex64的实部和虚部为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)
    拼接字符串str1str2用占位符%s的形式拼接字符串str1str2并赋值给变量str3。记住,fmt.Sprint拼接后的数据一定是string类型。所以你也可以
    fmt.Sprint("%d%d",int1,int2)
    把两个int类型转变为string类型。
  • 分割字符串
    strings.Split("待分割的字符串","分割符(可以是字符串)")
    分割字符串,分割后是[]string类型。
  • 判断包含
    strings.Contains('str1','str2')
    判断字符串str1中是否包含str2。返回booltrue或者false
  • 判断前缀
    strings.HasPrefix('str1','s')
    判断字符串在str1是不是以s开头,返回true
    strings.HasSuffixa('str1','str2')
    判断后缀。
  • 判断字符串出现的位置
    strings.Index('str1','a')
    判断字符串str1中字符a出现的位置返回-1表示从来没有出现过。
    strings.LastIndex('str1str1','r')
    判断字符串str1str1r最后一次出现的位置返回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类型同样道理啊。这个以后有时间在研究吧。(待续)。


  转载请注明: So Cold Go语言数据类型

 上一篇
指针和MAP类型 指针和MAP类型
声明指针指针也是一种数据类型,也可以使用var来声明:var 变量名 *数据类型注意,这里的变量名实际保存的数据是一个十六进制的内存地址,这里的数据类型指的是这个十六进制的内存地址要保存的数据类型。这里就生成了一个int类型的指针。 fun
2020-04-19
下一篇 
Go语言变量和常量 Go语言变量和常量
变量和常量变量变量只能一字母,数字或者下划线_开头。函数外面声明的变量属于全局变量,整个包不能重名。同一函数内的变量同理,不能重名。 声明变量声明变量有一下几种格式: 声明变量默认值为对应类型的空值,int=0,string="",boo
2020-03-06
  目录