跳转至

02 数据类型:你必须掌握的数据类型有哪些?

上节课的思考题是打印出自己的名字,作业比较简单,只需要把示例中的 "Hello, 世界" 替换为自己的名字(如 "飞雪无情")即可。

经过上一节课的学习,你已经对 Go 语言的程序结构有了初步了解,也准备好了相应的开发环境。但一个完整的项目需要更复杂的逻辑,由变量、常量、数据类型、函数、方法、接口和结构体共同组成。这节课我将带你认识变量、常量以及常用的数据类型。


变量声明

变量代表可变的数据类型,在程序执行过程中可以被修改。

在 Go 语言中,通过 var 声明语句定义变量,指定变量类型、变量名以及初始值:

var 变量名 类型 = 表达式

示例文件:ch02/main.go

package main

import "fmt"

func main() {
    var i int = 10
    fmt.Println(i)
}

Go 语言中声明的变量 必须被使用,否则无法编译通过。这有助于避免无用变量占用内存。

在终端中运行:

$ go run ch02/main.go
10

因为 Go 语言具备 自动类型推导 功能,因此也可以省略变量类型:

var i = 10

也可以使用括号一次性批量声明多个变量:

var (
    j int = 0
    k int = 1
)

或结合类型推导:

var (
    j = 0
    k = 1
)

不止 int 类型,后文介绍的 float64boolstring 等基础类型都可以自动推导。

演示项目目录结构

整个专栏的示例项目目录结构如下:

.
├── ch01
│   └── main.go
├── ch02
│   └── main.go
└── go.mod

基础数据类型

1. 整型

Go 语言中的整型分为:

  • 有符号整型intint8int16int32int64(可表示负数、零和正数);
  • 无符号整型uintuint8uint16uint32uint64(仅表示零和正数)。

intuint 的具体 bit 位数由 CPU 架构决定(32 位或 64 位)。如果数值大小不确定,推荐直接使用 int

此外,Go 语言中的 byte 类型等价于 uint8,是 uint8 的别名,专门用于表示一个字节。

2. 浮点数

Go 语言提供了两种精度的浮点数:float32float64。生产中最常用的是 float64,其计算精度更高。

var f32 float32 = 2.2
var f64 float64 = 10.3456
fmt.Println("f32 is", f32, ", f64 is", f64)

运行输出:

f32 is 2.2 , f64 is 10.3456

3. 布尔型

布尔型只有两个值:truefalse,使用关键字 bool 定义:

var bf bool = false
var bt bool = true
fmt.Println("bf is", bf, ", bt is", bt)

4. 字符串与字符串拼接

字符串使用 string 类型声明:

var s1 string = "Hello"
var s2 string = "世界"
fmt.Println("s1 is", s1, ", s2 is", s2)

使用 + 操作符可以将多个字符串拼接在一起:

fmt.Println(s1 + s2) // 输出: Hello世界

5. 变量的零值(默认值)

若声明了变量但未进行初始化,Go 语言会自动将其初始化为对应类型的零值:

  • 数字类型零值为 0
  • 浮点数零值为 0.0
  • 布尔型零值为 false
  • 字符串零值为 ""(空字符串)。

验证代码:

var zi int
var zf float64
var zb bool
var zs string
fmt.Println(zi, zf, zb, zs) // 输出: 0 0 false 

6. 变量简短声明 (:=)

借助类型推导,Go 语言提供了语法糖 := 进行变量的简短声明:

i := 10
bf := false
s1 := "Hello"

注意::= 只能用于函数内部,不能用于定义包级全局变量。

7. 指针

指针代表变量在内存中的存储地址。使用 & 操作符可获取变量的内存地址(指针);使用 * 运算符可解引用获取指针指向的变量值:

i := 10
pi := &i // pi 是指向 i 的指针 (*int)
fmt.Println(*pi) // 输出: 10

*pi = 20 // 修改指针指向的数据
fmt.Println("i 的新值是", i) // 输出: i 的新值是 20

常量定义与 iota

常量在编译期就已经确定,在运行期 不可被修改,防止关键数据被误篡改。

1. 常量定义

使用 const 关键字定义常量:

const name = "飞雪无情"

2. iota 常量生成器

iota 是 Go 语言的常量生成器,用于自动化生成连续递增的常量,避免手动书写:

普通不使用 iota 的定义:

const (
    one   = 1
    two   = 2
    three = 3
    four  = 4
)

使用 iota 简化定义:

package main

import "fmt"

const (
    one = iota + 1
    two
    three
    four
)

func main() {
    fmt.Println(one, two, three, four) // 输出: 1 2 3 4
}

iota 初始值为 0,在 const 声明块中每增加一行,iota 的值就会自增 1

  • one = (0) + 1 = 1
  • two = (1) + 1 = 2
  • three = (2) + 1 = 3
  • four = (3) + 1 = 4

字符串进阶与常用操作

1. 字符串与数字互转

Go 语言是强类型语言,不同类型在计算与赋值前必须显式转换。

数字与字符串互转使用标准库 strconv 包:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    // 数字转字符串
    i2s := strconv.Itoa(100)

    // 字符串转数字
    s2i, err := strconv.Atoi(i2s)
    fmt.Println(i2s, s2i, err)

    // 基础数字类型之间的强制转换
    var f64 float64 = 10.3456
    i2f := float64(100)
    f2i := int(f64)
    fmt.Println(i2f, f2i)
}

同理,浮点数与布尔型可以使用 strconv.ParseFloatstrconv.ParseBoolstrconv.FormatFloatstrconv.FormatBool 进行互转。

2. strings 工具包

标准库 strings 包提供了丰富的字符串处理函数:

package main

import (
    "fmt"
    "strings"
)

func main() {
    s1 := "Hello"

    // 判断前缀
    fmt.Println(strings.HasPrefix(s1, "H")) // true

    // 查找子串索引位置
    fmt.Println(strings.Index(s1, "o")) // 4

    // 转为大写
    fmt.Println(strings.ToUpper(s1)) // HELLO
}

总结

本课时讲解了 Go 语言中变量与常量的定义、简短声明 :=、指针的使用、基础数据类型(整型、浮点型、布尔型、字符串)、iota 常量生成器以及 strconvstrings 标准库的使用。

思考题: 如何在一个字符串中查找某个子字符串是否存在? 提示:Go 语言 strings 标准包中提供了 strings.Contains 函数。