GO语言基础:数据类型

8 阅读7分钟

我们继续学习 Go 语言的数据类型!数据类型决定了变量可以存储什么类型的值以及可以对它们进行哪些操作。Go 是静态类型语言,每个变量都有明确的类型,这有助于提高代码的安全性和可读性。

我们将数据类型分为两大类:基本数据类型复合数据类型


一、基本数据类型

基本数据类型是构成程序的基础,包括数字、字符串和布尔值。

1. 整数类型

Go 提供了多种整数类型,区别在于长度有无符号

类型说明取值范围
int平台相关,32位系统为32位,64位系统为64位有符号整数
int88位有符号整数-128 ~ 127
int1616位有符号整数-32768 ~ 32767
int3232位有符号整数-2147483648 ~ 2147483647
int6464位有符号整数-9223372036854775808 ~ 9223372036854775807
uint平台相关,无符号整数非负数
uint88位无符号整数0 ~ 255
uint1616位无符号整数0 ~ 65535
uint3232位无符号整数0 ~ 4294967295
uint6464位无符号整数0 ~ 18446744073709551615

💡 提示:日常开发中,如果不关心具体位数,直接使用 int 即可。当需要明确大小(如二进制协议、性能优化)时,使用指定长度的类型。

示例

var a int = 100
var b int8 = 10
var c uint = 200

sum := a + int(b)   // 不同类型需要显式转换
fmt.Println(sum)

2. 浮点数类型

Go 有两种浮点数类型:float32float64(常用)。

  • float32:约6位十进制精度
  • float64:约15位十进制精度

示例

var pi float64 = 3.141592653589793
var price float32 = 19.99
fmt.Printf("pi 类型:%T,值:%f\n", pi, pi)

3. 复数类型

Go 原生支持复数:complex64(实部和虚部都是float32)和 complex128(实部和虚部都是float64)。

示例

var c1 complex64 = 1 + 2i
c2 := 3 + 4i   // 类型推断为 complex128
fmt.Println(c1, c2)
fmt.Println(real(c1), imag(c1)) // 获取实部和虚部

4. 布尔类型

bool 类型只有两个值:truefalse。默认零值为 false

示例

var isOK bool = true
isReady := false
fmt.Println(isOK && isReady) // 逻辑运算

5. 字符串类型

string 是 Go 中的字符串类型,支持 Unicode,默认零值为空字符串 ""。字符串可以通过 + 连接。

示例

var name string = "Go语言"
greet := "Hello, " + name
fmt.Println(greet)
fmt.Println(len(name))            // 字节长度
fmt.Println(name[0])               // 访问第一个字节(非字符)

⚠️ 注意:字符串是不可变的,不能通过索引修改。

6. byte 和 rune 类型

  • byteuint8 的别名,通常表示 ASCII 字符。
  • runeint32 的别名,通常表示一个 Unicode 码点(即一个字符,可能占多个字节)。

示例

var b byte = 'A'       // 单引号表示字符
var r rune = '中'       // Unicode 字符
fmt.Printf("byte: %c, rune: %c\n", b, r)

二、复合数据类型

复合数据类型由基本数据类型组合而成,可以表示更复杂的数据结构。

1. 数组(Array)

数组是固定长度的同类型元素序列。长度是数组类型的一部分,一旦定义不可改变。

声明方式

var 数组名 [长度]元素类型
var 数组名 = [长度]元素类型{值1, 值2, ...}
数组名 := [...]元素类型{值1, 值2, ...}  // ... 让编译器自动计算长度

示例

var arr1 [3]int               // [0 0 0]
arr2 := [3]string{"a", "b"}   // ["a" "b" ""]  缺失的元素为零值
arr3 := [...]int{1, 2, 3, 4}  // 长度由初始化值决定

fmt.Println(arr2[0])          // 访问元素
arr1[1] = 10                   // 修改元素
fmt.Println(arr1)              // [0 10 0]

数组在 Go 中是值类型,赋值或传参会复制整个数组。

2. 切片(Slice)

切片是对数组的动态视图,长度可变,是 Go 中常用的数据结构。切片本身不存储数据,只是描述底层数组的一段。

声明方式

var s []int                     // nil 切片,长度0
s := []int{1, 2, 3}             // 创建切片并初始化
s := make([]int, 5)             // 创建长度为5的切片,元素为零值
s := make([]int, 5, 10)         // 长度为5,容量为10

常用操作

  • len(s) 获取长度
  • cap(s) 获取容量
  • append(s, 4, 5) 追加元素,可能扩容
  • s[low:high] 切片操作,左闭右开

示例

arr := [5]int{10, 20, 30, 40, 50}
s1 := arr[1:4]                // [20 30 40]
s2 := make([]int, 3)           // [0 0 0]
s2 = append(s2, 100)           // [0 0 0 100]

// 遍历切片
for i, v := range s1 {
    fmt.Printf("索引 %d: 值 %d\n", i, v)
}

💡 切片是引用类型,多个切片可能共享底层数组,修改会影响其他切片。

3. 映射(Map)

Map 是无序的键值对集合,键必须是可比较的类型(如基本类型、指针、数组、结构体等),值可以是任意类型。

声明方式

var m map[string]int          // nil 映射,不能直接赋值
m = make(map[string]int)      // 初始化
m := map[string]int{"age": 18, "score": 100}

常用操作

  • m[key] = value 插入或修改
  • value, ok := m[key] 获取值,ok 表示键是否存在
  • delete(m, key) 删除键值对
  • len(m) 获取元素个数

示例

scores := map[string]int{
    "小明": 90,
    "小红": 85,
}
scores["小刚"] = 95          // 新增
delete(scores, "小红")       // 删除

if score, ok := scores["小明"]; ok {
    fmt.Println("小明的分数:", score)
}

4. 结构体(Struct)

结构体是将零个或多个任意类型的变量组合在一起的复合类型,类似于其他语言中的“类”,但只有字段,没有方法(方法可以单独定义)。

定义与使用

type Person struct {
    Name string
    Age  int
}

func main() {
    // 初始化方式
    var p1 Person                // 字段为零值
    p2 := Person{"张三", 30}      // 顺序必须一致
    p3 := Person{Name: "李四", Age: 25} // 推荐,指定字段名
    p4 := new(Person)             // 返回指针,字段为零值

    // 访问和修改字段
    p1.Name = "王五"
    p1.Age = 28
    fmt.Println(p1.Name, p1.Age)
}

结构体是值类型,赋值或传参会复制整个结构体。如果希望共享,可以使用指针。

5. 其他复合类型简介

  • 指针(Pointer)*T 表示指向类型 T 的指针。用于间接访问变量值。
  • 函数(Function):函数也是一种类型,可以赋值给变量、作为参数或返回值。
  • 接口(Interface):定义一组方法签名,实现多态。
  • 通道(Channel):用于 goroutine 之间的通信。

这些属于进阶内容,待你熟悉基础后再深入学习。


三、类型转换

Go 不支持隐式类型转换,不同类型之间必须显式转换。

语法T(v) 将值 v 转换为类型 T

示例

var i int = 42
var f float64 = float64(i)   // int 转 float64
var u uint = uint(f)          // float64 转 uint

⚠️ 转换时要注意精度丢失或溢出。


四、零值

在 Go 中,任何变量在声明后如果没有显式初始化,都会被赋予对应类型的零值。零值是类型默认值,不会出现未定义行为。

类型零值
数值类型(int, float等)0
布尔类型false
字符串""(空字符串)
指针、切片、映射、通道、函数、接口nil
数组每个元素为其类型的零值
结构体每个字段为其类型的零值

总结

  • 基本数据类型:整数、浮点数、复数、布尔、字符串、byte/rune,是构建程序的基础砖块。
  • 复合数据类型:数组(固定长度)、切片(动态长度)、映射(键值对)、结构体(字段集合),用于组织和操作更复杂的数据。
  • 每种类型都有其特性和用途,选择正确的类型能让代码更清晰、高效。
  • 记住零值的概念,避免未初始化变量的困扰。