Xavier's Blog

做更美好的自己

Go 了解基本数据类型

golang

了解基本数据类型

Go 是一种强类型语言。 这意味着你声明的每个变量都绑定到特定的数据类型,并且只接受与此类型匹配的值。

Go 有四类数据类型:

  • 基本类型:数字、字符串和布尔值
  • 聚合类型:数组和结构
  • 引用类型:指针、切片、映射、函数和通道
  • 接口类型:接口

在此模块中,我们仅介绍基本类型。 如果你不知道其他类型是什么,请不要担心。 我们将在后续模块中进行介绍。

首先,我们一起浏览数值的数据类型。

整数数字

一般来说,定义整数类型的关键字是 int。 但 Go 还提供了 int8int16int32int64 类型,其大小分别为 8、16、32 或 64 位的整数。 当你只使用 int 时,32 位系统上的大小为 32 位,64 位系统上则为 64 位(大多数情况下如此,不过在不同计算机上或有所不同)。 如果需要将值表示为无符号数字,则可以使用 uint,但仅当有特定原因时才使用此类型。 此外,Go 还提供 uint8uint16uint32uint64 类型。

下面的示例演示如何在 Go 中使用各种整数类型:

var integer8 int8 = 127
var integer16 int16 = 32767
var integer32 int32 = 2147483647
var integer64 int64 = 9223372036854775807
println(integer8, integer16, integer32, integer64)

大多数情况下,你将使用 int,但需要了解其他整数类型,因为在 Go 中,intint32 不同,即使整数的自然大小为 32 位也是如此。 换句话说,需要强制转换时,你需要进行显式转换。 如果尝试在不同类型之间执行数学运算,将会出现错误。 例如,假定你具有下面的代码:

var integer16 int16 = 127
var integer32 int32 = 32767
println(integer16 + integer32)

运行该程序时,你会收到以下错误:

输出

invalid operation: integer16 + integer32 (mismatched types int16 and int32)

正如你所见,不同于其他编程语言,在 Go 中将值从一种类型转换为另一种类型时,你需要执行显式操作。 我们将在本模块结束时讨论如何正确地强制转换类型。

在学习 Go 过程中,你可能会收到有关 runes 的信息。 rune 只是 int32 数据类型的别名。 它用于表示 Unicode 字符(或 Unicode 码位)。 例如,假设你具有以下代码:

rune := 'G'
println(rune)

运行前面的代码片段时,你可能会在命令提示符下看到程序打印符 G。 不过,你还会看到数字 71,它表示 G 的 Unicode 字符。 我们将在后续模块中详细介绍 runes。

你可以通过查看 Go 源代码来了解每种类型的范围。 了解每种类型的范围可帮助你选择正确的数据类型,并且还可避免占用内存中的位。

挑战 1

设置 int 类型的另一个变量,并使用 integer32integer64 变量中的值来确认系统上变量的自然大小。 如果你使用的是 32 位系统并使用大于 2,147,483,647 的值,则会出现如下的溢出错误:constant 9223372036854775807 overflows int

质询解决方案

> package main
> 
> func main() {
>    var integer32 int = 2147483648
>    println(integer32)
> }
> ```

### 挑战 2

声明一个无符号变量(如 `uint`),并用一个负值(如 `-10`)对其进行初始化。 尝试运行程序时,应会出现如下错误:`constant -10 overflows uint`。

> **质询解决方案**:
>
> ```go
> package main
> 
> func main() {
>    var integer uint = -10
>    println(integer)
> }
> ```

## 浮点数字

Go 提供两种浮点数大小的数据类型:`float32` 和 `float64`。 如果需要存储较大的数字,则可以使用这些类型,这些类型无法适应前面提到的任何一个整数类型。 这两种类型的区别是它们可以容纳的最大位数。 查看以下行,了解如何使用这两种类型:

Go

```go
var float32 float32 = 2147483647
var float64 float64 = 9223372036854775807
println(float32, float64)

你可以使用 math 包中提供的 math.MaxFloat32math.MaxFloat64 常量来查找这两种类型的限制。 使用以下代码打印命令提示符中的最大浮点值:

Go

package main

import "math"

func main() {
    println(math.MaxFloat32, math.MaxFloat64)
}

当需要使用十进制数时,浮点类型也很有用。 例如,你可以编写类似于以下代码的内容:

Go

const e = 2.71828
const Avogadro = 6.02214129e23
const Planck = 6.62606957e-34

请注意,与前面的代码一样,Go 会从使用的值推断其数据类型。

布尔型

布尔类型仅可能有两个值:truefalse。 你可以使用关键字 bool 声明布尔类型。 Go 不同于其他编程语言,在 Go 中,你不能将布尔类型隐式转换为 0 或 1。 你必须显式执行此操作。

因此,你可以按如下方式声明布尔变量:

Go

var featureFlag bool = true

当我们讨论 Go 中的控制流语句时,我们将在后续模块中使用布尔数据类型。 我们还将在以后的模块中使用这些类型。

字符串

最后,让我们看一下编程语言中最常见的数据类型:string。 在 Go 中,关键字 string 用于表示字符串数据类型。 若要初始化字符串变量,你需要在双引号(")中定义值。 单引号(')用于单个字符(以及 runes,正如我们在上一节所述)。

例如,下面的代码演示了声明和初始化字符串变量的两种方法:

Go

var firstName string = "John"
lastName := "Doe"
println(firstName, lastName)

有时,你需要对字符进行转义。 为此,在 Go 中,请在字符之前使用反斜杠 (\)。 例如,下面是使用转义字符的最常见示例:

  • \n:新行
  • \r:回车符
  • \t:选项卡
  • \':单引号
  • \":双引号
  • \\:反斜杠

使用以下代码片段来测试转义字符:

Go

fullName := "John Doe \t(alias \"Foo\")\n"
println(fullName)

你应会看到以下输出(包括新行):

输出

John Doe        (alias "Foo")

默认值

到目前为止,几乎每次声明变量时,都使用值对其进行了初始化。 但与在其他编程语言中不同的是,在 Go 中,如果你不对变量初始化,所有数据类型都有默认值。 此功能非常方便,因为在使用之前,你无需检查变量是否已初始化。

下面列出了我们目前浏览过类型的几个默认值:

  • int 类型的 0(及其所有子类型,如 int64
  • float32float64 类型的 +0.000000e+000
  • bool 类型的 false
  • string 类型的空值

运行以下代码片段以确认前面列出的默认值:

输出

var defaultInt int
var defaultFloat32 float32
var defaultFloat64 float64
var defaultBool bool
var defaultString string
println(defaultInt, defaultBool, defaultFloat32, defaultFloat64, defaultString)

你可以使用类似于此代码的代码来确定我们没有浏览到的数据类型默认值。

类型转换

在上一节中,我们确认在 Go 中隐式强制转换不起作用。 接下来,需要显式强制转换。 Go 提供了将一种数据类型转换为另一种数据类型的一些本机方法。 例如,一种方法是对每个类型使用内置函数,如下所示:

Go

var integer16 int16 = 127
var integer32 int32 = 32767
println(int32(integer16) + integer32)

Go 的另一种转换方法是使用 strconv 包。 例如,若要将 string 转换为 int,可以使用以下代码,反之亦然:

Go

package main

import "strconv"

func main() {
    i, _ := strconv.Atoi("-42")
    s := strconv.Itoa(-42)
    println(i, s)
}

运行前面的代码,并确认它运行并打印 -42 两次。

请注意,在前面的代码中,有一个下划线 (_) 用作变量的名称。 在 Go 中,这意味着我们不会使用该变量的值,而是要将其忽略。 否则,程序将不会进行编译,因为我们需要使用声明的所有变量。 我们将返回到本主题,届时你将在后续模块中了解 _ 通常表示的内容。