第 5 章 基础数据类型

在静态类型语言(C++/Java/Golang 等)中规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存。

5.1 整形

整型分两大类

  • 有符号整型:int8、int16、int32、int64、int。
  • 无符号整型:uint8、uint16、uint32、uint64、uint。
类型 取值范围
int8 [-128 , 127]
int16 [-32768 , 32767]
int32 [-2147483648 , 2147483647] Go语言中没有字符类型,所有字符都使用int32存储
int64 [-9223372036854775808 , 9223372036854775807]
int 受限于计算机系统,系统是多少位,int为多少位
uint8 [0 , 255]
uint16 [0 , 65535]
uint32 [0 , 4294967295]
uint64 [0 , 18446744073709551615]
uint 受限于计算机系统,系统是多少位,uint为多少位
rune 与int32类似,常用在获取值的Unicode码
byte 与uint8类似.强调值为原始数据.一个字节占用8个二进制
uintptr 大小不确定,类型取决于底层编程

示例程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package main

import (
"fmt"
"math"
"unsafe"
)

// 有符号整型
func Integer() {
var num8 int8 = 127
var num16 int16 = 32767
var num32 int32 = math.MaxInt32
var num64 int64 = math.MaxInt64
var num int = math.MaxInt
fmt.Printf("num8的类型是 %T, num8的大小 %d, num8是 %d\n",
num8, unsafe.Sizeof(num8), num8)
fmt.Printf("num16的类型是 %T, num16的大小 %d, num16是 %d\n",
num16, unsafe.Sizeof(num16), num16)
fmt.Printf("num32的类型是 %T, num32的大小 %d, num32是 %d\n",
num32, unsafe.Sizeof(num32), num32)
fmt.Printf("num64的类型是 %T, num64的大小 %d, num64是 %d\n",
num64, unsafe.Sizeof(num64), num64)
fmt.Printf("num的类型是 %T, num的大小 %d, num是 %d\n",
num, unsafe.Sizeof(num), num)
}

// 无符号整型
func unsignedInteger() {
var num8 uint8 = 128
var num16 uint16 = 32768
var num32 uint32 = math.MaxUint32
var num64 uint64 = math.MaxUint64
var num uint = math.MaxUint
fmt.Printf("num8的类型是 %T, num8的大小 %d, num8是 %d\n",
num8, unsafe.Sizeof(num8), num8)
fmt.Printf("num16的类型是 %T, num16的大小 %d, num16是 %d\n",
num16, unsafe.Sizeof(num16), num16)
fmt.Printf("num32的类型是 %T, num32的大小 %d, num32是 %d\n",
num32, unsafe.Sizeof(num32), num32)
fmt.Printf("num64的类型是 %T, num64的大小 %d, num64是 %d\n",
num64, unsafe.Sizeof(num64), num64)
fmt.Printf("num的类型是 %T, num的大小 %d, num是 %d\n",
num, unsafe.Sizeof(num), num)
}

func main() {
Integer()
println("---------------------------------------")
unsignedInteger()
}

Tips:

  • 除非对整型的大小有特定的需求,否则你通常应该使用 int 表示整型宽度,在 32 位系统下是 32 位,而在 64 位系统下是 64 位。表示范围:在 32 位系统下是 -2147483648 ~ 2147483647 ,而在 64 位系统是 -9223372036854775808 ~ 9223372036854775807
  • 对于 int8int16 等这些类型后面有跟一个数值的类型来说,它们能表示的数值个数是固定的。所以,在有的时候:例如在二进制传输、读写文件的结构描述(为了保持文件的结构不会受到不同编译目标平台字节长度的影响)等情况下,使用更加精确的 int32int64 是更好的。

5.2 浮点型

浮点型表示存储的数据是实数,如 3.145。关于浮点型的说明,如表所示。

类型 字节数 说明
float32 4 32 位的浮点型
float64 8 64 位的浮点型

示例程序:

1
2
3
4
5
6
7
8
9
10
func showFloat() {
var num1 float32 = math.MaxFloat32
var num2 float64 = math.MaxFloat64
fmt.Printf("num1的类型是%T,num1是%g\n", num1, num1)
fmt.Printf("num2的类型是%T,num1是%g\n", num2, num2)
}

func main() {
showFloat()
}

Tips:

  • 通过上面的程序,我们知道浮点数能表示的数值很大,但是浮点数的精度却没有那么大:
    • float32 的精度只能提供大约 6 个十进制数(表示小数点后 6 位)的精度。
    • float64 的精度能提供大约 15 个十进制数(表示小数点后 15 位)的精度。

5.3 字符

字符串中的每一个元素叫作“字符”,定义字符时使用单引号。Go 语言的字符有两种,如表所示。

类 型 字 节 数 说 明
byte 1 表示 UTF-8 字符串的单个字节的值,表示的是 ASCII 码表中的一个字符,uint8 的别名类型
rune 4 表示单个 unicode 字符,int32 的别名类型

声明示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func showChar() {
var x byte = 65
var y uint8 = 65
fmt.Printf("x = %c\n", x) // x = A
fmt.Printf("y = %c\n", y) // y = A
}

func sizeOfChar() {
var x byte = 65
fmt.Printf("x = %c\n", x)
fmt.Printf("x 占用 %d 个字节\n", unsafe.Sizeof(x))

var y rune = 'A'
fmt.Printf("y = %c\n", y)
fmt.Printf("y 占用 %d 个字节\n", unsafe.Sizeof(y))
}

func main() {
showChar();
sizeOfChar();
}

Tips:

  • 由此可见, byte 类型只能表示 28个值,所以你想表示其他一些值,例如中文的话,就得使用 rune 类型

    1
    var y rune = '牛'

5.4 字符串

字符串在 Go 语言中是以基本数据类型出现的,使用字符串就像使用其他原生基本数据类型 int、float32、float64、bool 一样。

示例程序:

1
2
3
4
var study string  	 		// 定义名为str的字符串类型变量
study = "《Go语言极简一本通》" // 将变量赋值

study2 := "《从0到Go语言微服务架构师》" // 以自动推断方式初始化

有些字符串没有现成的文字代号,所以只能用转义字符来表示。常用的转义字符如表所示。

转 义 字 符 含 义
\r 回车符 return,返回行首
\n 换行符 new line, 直接跳到下一行的同列位置
\t 制表符 TAB
\' 单引号
\" 双引号
\\ 反斜杠

定义多行字符串的方法如下。

  • 双引号书写字符串被称为字符串字面量(string literal),这种字面量不能跨行。
  • 多行字符串需要使用反引号“`”,多用于内嵌源码和内嵌数据。
  • 在反引号中的所有代码不会被编译器识别,而只是作为字符串的一部分。

多行字符串定义方式如例所示:

1
2
3
4
5
6
7
8
9
10
11
package main
import "fmt"

func main() {
var s1 string
s1 = `
study := 'Go语言微服务架构核心22讲'
fmt.Println(study)
`
fmt.Println(s1)
}

5.3 布尔类型

关于 布尔(bool) 类型,无非就是两个值:true 或者 false

示例程序:

1
2
3
4
5
6
7
8
9
10
11
12
func showBool(){
a := true
b := false
fmt.Println("a=", a)
fmt.Println("b=", b)
fmt.Println("true && false = ", a && b)
fmt.Println("true || false = ", a || b)
}

func main() {
showBool()
}

Tip:

  • 如果你学过其他编程语言或许会发现,布尔型可以参与数值运算,也可以与其他类型进行转换。但是在 Go 中,真值是用 true 表示,并且 不与 1 相等;同样的,假值是用 false 表示,并且 不与 0 相等。

5.4 复数型

复数型用于表示数学中的复数,如 1+2j、1-2j、-1-2j 等。在 Go 语言中提供了两种精度的复数类型:complex64complex128 ,分别对应 float32 和 float64 两种浮点数精度,如表所示。

类 型 字 节 数 说 明
complex64 8 64 位的复数型,由 float32 类型的实部和虚部联合表示
complex128 16 128 位的复数型,由 float64 类型的实部和虚部联合表示

示例程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func showComplex() {
// 内置的 complex 函数用于构建复数
var x complex64 = complex(1, 2)
var y complex128 = complex(3, 4)
var z complex128 = complex(5, 6)
fmt.Println("x = ", x)
fmt.Println("y = ", y)
fmt.Println("z = ", z)

// 内建的 real 和 imag 函数分别返回复数的实部和虚部
fmt.Println("real(x) = ", real(x))
fmt.Println("imag(x) = ", imag(x))
fmt.Println("y * z = ", y*z)
}

func main() {
showComplex()
}

Tip:

  • 当然,我们可以对声明进行简化,使用自然的方式书写复数:

    1
    2
    3
    x := 1 + 2i
    y := 3 + 4i
    z := 5 + 6i

5.5 fmt 格式输出

格式 含义
%% 一个%字面量
%b 一个二进制整数值(基数为 2),或者是一个(高级的)用科学计数法表示的指数为 2 的浮点数
%c 字符型。可以把输入的数字按照 ASCII 码相应转换为对应的字符
%d 一个十进制数值(基数为 10)
%f 以标准记数法表示的浮点数或者复数值
%o 一个以八进制表示的数字(基数为 8)
%p 以十六进制(基数为 16)表示的一个值的地址,前缀为 0x,字母使用小写的 a-f 表示
%q 使用 Go 语法以及必须时使用转义,以双引号括起来的字符串或者字节切片[]byte,或者是以单引号括起来的数字
%s 字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符)
%t 以 true 或者 false 输出的布尔值
%T 使用 Go 语法输出的值的类型
%x 以十六进制表示的整型值(基数为十六),数字 a-f 使用小写表示
%X 以十六进制表示的整型值(基数为十六),数字 A-F 使用小写表示

如何学习Go语言微服务,快速步入架构师

从0到Go语言微服务架构师-海报 从0到Go语言微服务架构师
添加微信 公众号更多内容
wechat gzh