数据类型概述

Go 语言按类别有以下几种数据类型:

  • 布尔型

布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。

  • 数字类型

整型 int、uint 和 uintptr 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。

  • uint:32 或 64 位
  • uint8:无符号 8 位整型 (0 到 255)
  • uint16:无符号 16 位整型 (0 到 65535)
  • uint32:无符号 32 位整型 (0 到 4294967295)
  • uint64:无符号 64 位整型 (0 到 18446744073709551615)
  • int:与 uint 一样大小
  • int8:有符号 8 位整型 (-128 到 127)
  • int16:有符号 16 位整型 (-32768 到 32767)
  • int32:有符号 32 位整型 (-2147483648 到 2147483647)
  • int64:有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)
  • uintptr:无符号整型,用于存放一个指针
  • float32:IEEE-754 32位浮点型数
  • float64:IEEE-754 64位浮点型数
  • complex64:32 位实数和虚数
  • complex128:64 位实数和虚数
  • byte:类似 uint8
  • rune:类似 int32
  • 字符串类型

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

  • 派生类型

数字

整数

如果声明类型为 intuint ,则其宽度(宽度即指存储一个某类型的值所需要的空间。空间的单位可以是比特,也可以是字节(byte)。)与计算机的计算架构有关。
5529fa8c0001211009020290.png
除了这两个计算架构相关的整数类型之外,还有8个可以显式表达自身宽度的整数类型。如下表所示。
5529fac20001b2f506320482.png

整数类型值的表示范围

552a276d0001663510160280.png

进制

  • 十进制数表示方法: num := 12 ,格式化参数使用 %d 表示
  • 八进制数表示方法: num := 014
  • 十六进制数表示方法: num := 0xC ,格式化参数使用 %x 表示

浮点数

浮点数类型有两个,即float32float64。存储这两个类型的值的空间分别需要4个字节8个字节

浮点数类型的值一般由整数部分、小数点“.”和小数部分组成。其中,整数部分和小数部分均由10进制表示法表示。不过还有另一种表示方法。那就是在其中加入指数部分。指数部分由“E”或“e”以及一个带正负号的10进制数组成。比如,3.7E-2表示浮点数0.037。又比如,3.7E+1表示浮点数37。

有时候,浮点数类型值的表示也可以被简化。比如,37.0可以被简化为37。又比如,0.037可以被简化为.037。

有一点需要注意,在Go语言里,浮点数的相关部分只能由10进制表示法表示,而不能由8进制表示法或16进制表示法表示。比如,03.7表示的一定是浮点数3.7。

在格式化参数中:

  • %E 用于以带指数部分的表示法显示浮点数类型值
  • %f 用于以通常的方法显示浮点数类型值

复数

复数类型同样有两个,即complex64complex128。存储这两个类型的值的空间分别需要8个字节16个字节。实际上,complex64类型的值会由两个float32类型的值分别表示复数的实数部分和虚数部分。而complex128类型的值会由两个float64类型的值分别表示复数的实数部分和虚数部分。

复数类型的值一般由浮点数表示的实数部分、加号“+”、浮点数表示的虚数部分,以及小写字母“i”组成。比如,3.7E+1 + 5.98E-2i。正因为复数类型的值由两个浮点数类型值组成,所以其表示法的规则自然需遵从浮点数类型的值表示法的相关规则。

举例:

  1. num := 3.7E+1 + 5.98E-2i
  2. fmt.Println(num) // (37+0.0598i)

在格式化参数中,复数仍然可以用 %E%f 表示。

byte和rune

byte与rune类型有一个共性,即:它们都属于别名类型。byte是uint8的别名类型,而rune则是int32的别名类型。

byte类型的值需用8个比特位表示,其表示法与uint8类型无异。

一个rune类型的值即可表示一个Unicode字符。Unicode是一个可以表示世界范围内的绝大部分字符的编码规范。详细信息可以参看:http://unicode.org/https://unicode-table.com/cn/。用于代表Unicode字符的编码值也被称为Unicode代码点。一个Unicode代码点通常由“U+”和一个以十六进制表示法表示的整数表示。例如,英文字母“A”的Unicode代码点为“U+0041”。
rune类型的值需要由单引号'”包裹。例如,’A’或’昱’。这种表示方法一目了然。不过,我们还可以用另外几种形式表示rune类型值。见下表。
555057750001750c12480480.png
在rune类型值的表示中支持几种特殊的字符序列,即:转义符。它们由“\”和一个单个英文字符组成。如下表所示。
555057a90001ad4808900830.png
举例:

var char rune = '昱'
fmt.Printf("字符 %c 的 unicode 为 %x", char, char) // 字符 昱 的 unicode 为 6631

这意味着可以这样输出这个汉字:

fmt.Printf("\u6631 is %x", '昱') // 昱 is 6631

if '\u6631' == '昱' {
    fmt.Println(1)
}

字符串

一个字符串类型的值可以代表一个字符序列。这些字符必须是被Unicode编码规范支持的。虽然从表象上来说是字符序列,但是在底层,一个字符串值却是由若干个字节来表现和存储的。一个字符串(也可以说字符序列)会被Go语言用Unicode编码规范中的UTF-8编码格式编码为字节数组

:::info 注意:我们在一个字符串值或者一个字符串类型的变量之上应用Go语言的内置函数len将会得到代表它的那个字节数组的长度。这可能与我们看到的表象是不同的。 :::

字符串的表示法有两种,即:原生表示法和解释型表示法。若用原生表示法,需用反引号“``”把字符序列包裹起来。若用解释型表示法,则需用双引号““`”包裹字符序列。

二者的区别是,前者表示的值是所见即所得的(除了回车符)。在那对反引号之间的内容就是该字符串值本身。而后者所表示的值中的转义符会起作用并在程序编译期间被转义。所以,如此表示的字符串值的实际值可能会与我们看到的表象不相同。

最后要注意,字符串值是不可变的。也就是说,我们一旦创建了一个此类型的值,就不可能再对它本身做任何修改。

转义

使用 \ 符号表示转义字符:

var str string = "\\\""
fmt.Printf("%q ---> %s", str, str) // "\\\"" ---> \"

将转义字符放于 ```` 中不会被转义:

fmt.Println(`\\\"`) // \\\"

在格式化参数中:

  • %q 表示字符串的表象值,包括转移符及双引号
  • %s 表示字符串的真实值,转义后的值

数组

一个数组(Array)就是一个可以容纳若干类型相同的元素的容器。这个容器的大小(即数组的长度)是固定的,且是体现在数组的类型字面量之中的。

数组的声明:

var variable_name [SIZE] variable_type

数组的定义:

var variable_name = [SIZE]variable_type{初始化值1, 初始化值2, ...}

示例:

nums := [...]int{1,2,3}
println(nums)
println(nums[0])

定义新的数组类型

可以通过 type 关键字定义新的数组类型:

type MyNumbers [3]int
nums := MyNumbers{1,2,3}

fmt.Println(nums)

数组长度和容量

使用 len 方法获取数组长度, cap 方法获取数组的容量:

nums := [3]int{1,2,3}
fmt.Println(len(nums), cap(nums))

切片

切片(Slice)与数组一样,也是可以容纳若干类型相同的元素的容器。与数组不同的是,无法通过切片类型来确定其值的长度。每个切片值都会将数组作为其底层数据结构。我们也把这样的数组称为切片的底层数组。

创建切片:

numbers := []int{1, 2, 3, 4, 5}

从数组中获取切片:

numbers := [5]int{1, 2, 3, 4, 5}
slice := numbers[1:4]
fmt.Println(slice, len(slice)) // [2 3 4] 3

Map

Go语言的字典(Map)类型其实是哈希表(Hash Table)的一个实现。字典用于存储键-元素对(更通俗的说法是键-值对)的无序集合。注意,同一个字典中的每个键都是唯一的。如果我们在向字典中放入一个键值对的时候其中已经有相同的键的话,那么与此键关联的那个值会被新值替换。

Map的声明:

/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type

/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)

Map的定义:

var map_variable = map[key_data_type]value_data_type{key1: value1, key2: value2, ...}

示例:

stringMap := map[string]string{}

stringMap["1"] = "A"
stringMap["2"] = "B"
stringMap["3"] = "V"
stringMap["4"] = "D"

类型转换

在需要转换的数据前面使用目标数据类型包裹即可:

type_name(expression)