引入

程序要处理各种数据,有的是一个数字,有的是一段文本,还有的是一组记录。用于告诉编译器数据是什么种类,Go 是强类型语言,类型必须明确。搞清楚 Go 有哪些数据类型,是写出正确代码的前提。

正文

定义

定义

Go 数据类型分为基本类型(整型、浮点型、布尔型、字符串)和复合类型(数组、切片、map、结构体、指针、通道、接口、函数)。每种类型都有对应的零值,可以通过 reflect.TypeOf() 或类型断言来判断一个值的具体类型。

语法

// 基本类型
var n int = 10
var f float64 = 3.14
var b bool = true
var s string = "hello"
 
// 复合类型
var arr [3]int = [3]int{1, 2, 3}
var sl []int = []int{1, 2, 3}
var m map[string]int = map[string]int{"a": 1}

例子

基本类型一览

var age int = 25
var price float64 = 9.99
var active bool = true
var name string = "Go"
 
fmt.Println(age, price, active, name)
// 25 9.99 true Go

复合类型一览

// 数组:固定长度
arr := [3]int{10, 20, 30}
 
// 切片:动态长度
sl := []int{1, 2, 3}
 
// Map:键值对
m := map[string]int{
    "语文": 90,
    "数学": 95,
}
 
// 结构体:自定义字段组合
type User struct {
    Name string
    Age  int
}
u := User{Name: "Tom", Age: 20}
 
// 指针:存储变量的内存地址
p := &age
 
fmt.Println(arr, sl, m, u, *p)

零值

每种类型声明后不赋值,Go 会自动赋予零值

var n int       // 0
var f float64   // 0
var b bool      // false
var s string    // ""
var p *int      // nil
var sl []int    // nil
var m map[string]int  // nil
var ch chan int       // nil
var fn func()        // nil
var i interface{}     // nil
类型零值
intfloat64 等数值型0
string""
boolfalse
指针、切片、map、channel、接口、函数nil
数组每个元素为零值
结构体每个字段为零值

类型判断

import "reflect"
 
var x interface{} = "hello"
 
// reflect.TypeOf 获取类型
fmt.Println(reflect.TypeOf(x)) // string
 
// 类型断言
if s, ok := x.(string); ok {
    fmt.Println("是字符串:", s)
}
 
// type switch
switch v := x.(type) {
case int:
    fmt.Println("整数:", v)
case string:
    fmt.Println("字符串:", v)
default:
    fmt.Println("其他类型")
}

fmt.Printf 查看类型

fmt.Printf("%T\n", 42)       // int
fmt.Printf("%T\n", 3.14)     // float64
fmt.Printf("%T\n", true)     // bool
fmt.Printf("%T\n", "hello")  // string
fmt.Printf("%T\n", []int{})  // []int

%T 是调试时快速查看变量类型的好办法。

常见写法

写法说明
var x int = 10基本类型,显式指定
var x = 10基本类型,编译器推断
x := 10短变量声明,函数内常用
type User struct{…}定义复合类型(结构体)
reflect.TypeOf(x)运行时获取类型
x.(T)类型断言
fmt.Printf("%T", x)格式化输出类型

特点

  • Go 是强类型语言,不同类型之间不能随意转换,必须显式转换
  • 基本类型是语言内置的,复合类型由基本类型组合而成
  • 每种类型都有零值,不会出现未初始化的内存垃圾
  • nil 是引用类型(指针、切片、map、channel、接口、函数)的零值
  • reflect.TypeOf() 用于运行时类型判断,编译时一般不需要
  • 类型断言 x.(T) 只能用于接口类型的值

理解

Go 的类型系统分两层:基本类型是砖块(intfloat64boolstring),复合类型是用砖块搭的房子(数组、切片、map、结构体等)。零值机制让你声明变量就有默认值,不用手动初始化。类型判断用 reflect 或类型断言,但大多数时候编译器在编译阶段就帮你搞定了。

引出

数据类型分基本类型和复合类型两大类,接下来深入看基本类型的具体成员。Go 基本类型 会详细介绍整型、浮点型、布尔型和字符串的用法。