数据类型

数据类型是编程语言的基础。Go 语言是静态类型语言,每个变量都有明确的类型。本章将详细介绍 Go 语言的数据类型。

数据类型概览

Go 语言的数据类型分为以下几类:

Go 数据类型
├── 基本类型
│   ├── 布尔类型:bool
│   ├── 数值类型
│   │   ├── 整数:int, int8, int16, int32, int64
│   │   ├── 无符号整数:uint, uint8, uint16, uint32, uint64
│   │   ├── 浮点数:float32, float64
│   │   └── 复数:complex64, complex128
│   └── 字符串:string
├── 复合类型
│   ├── 数组:[n]T
│   ├── 切片:[]T
│   ├── 映射:map[K]V
│   └── 结构体:struct
├── 引用类型
│   ├── 指针:*T
│   ├── 切片:[]T
│   ├── 映射:map[K]V
│   ├── 通道:chan T
│   └── 函数:func
└── 接口类型
    └── interface

布尔类型

布尔类型只有两个值:truefalse

声明和使用

package main

import "fmt"

func main() {
    var isActive bool = true
    var hasPermission bool = false

    fmt.Println("isActive:", isActive)
    fmt.Println("hasPermission:", hasPermission)

    result := 10 > 5
    fmt.Println("10 > 5:", result)
}

输出:

isActive: true
hasPermission: false
10 > 5: true

注意事项

  1. 布尔类型默认值是 false
  2. 布尔类型不能参与数值运算
  3. 布尔类型不能与其他类型转换
var b bool = true
var i int = int(b)

整数类型

Go 提供了多种整数类型,分为有符号和无符号两类。

有符号整数

类型大小范围
int81 字节-128 ~ 127
int162 字节-32768 ~ 32767
int324 字节-2147483648 ~ 2147483647
int648 字节-9223372036854775808 ~ 9223372036854775807
int平台相关32 位系统为 int32,64 位系统为 int64

无符号整数

类型大小范围
uint81 字节0 ~ 255
uint162 字节0 ~ 65535
uint324 字节0 ~ 4294967295
uint648 字节0 ~ 18446744073709551615
uint平台相关32 位系统为 uint32,64 位系统为 uint64

特殊整数类型

类型说明
byteuint8 的别名,常用于处理字节数据
runeint32 的别名,常用于处理 Unicode 字符
uintptr无符号整数,用于存储指针

示例

package main

import "fmt"

func main() {
    var i int = 100
    var i8 int8 = 127
    var i16 int16 = 32767
    var i32 int32 = 2147483647
    var i64 int64 = 9223372036854775807

    var u uint = 100
    var u8 uint8 = 255
    var u16 uint16 = 65535

    var b byte = 255
    var r rune = '中'

    fmt.Printf("int: %d\n", i)
    fmt.Printf("int8: %d\n", i8)
    fmt.Printf("int16: %d\n", i16)
    fmt.Printf("int32: %d\n", i32)
    fmt.Printf("int64: %d\n", i64)
    fmt.Printf("uint: %d\n", u)
    fmt.Printf("uint8: %d\n", u8)
    fmt.Printf("uint16: %d\n", u16)
    fmt.Printf("byte: %d\n", b)
    fmt.Printf("rune: %c (Unicode: %U)\n", r, r)
}

整数溢出

整数溢出不会报错,但会产生错误结果:

package main

import "fmt"

func main() {
    var i int8 = 127
    fmt.Println("i:", i)

    i = i + 1
    fmt.Println("i + 1:", i)
}

输出:

i: 127
i + 1: -128

注意:使用整数时要注意范围,避免溢出。

浮点数类型

Go 提供了两种浮点数类型:float32float64

类型大小精度
float324 字节约 7 位小数
float648 字节约 15 位小数(推荐)

示例

package main

import "fmt"

func main() {
    var f32 float32 = 3.14159265358979323846
    var f64 float64 = 3.14159265358979323846

    fmt.Printf("float32: %.15f\n", f32)
    fmt.Printf("float64: %.15f\n", f64)
}

输出:

float32: 3.141592741012573
float64: 3.141592653589793

注意:float64 精度更高,推荐使用。

科学计数法

package main

import "fmt"

func main() {
    f1 := 1.23e5
    f2 := 1.23e-5

    fmt.Printf("1.23e5 = %f\n", f1)
    fmt.Printf("1.23e-5 = %f\n", f2)
}

输出:

1.23e5 = 123000.000000
1.23e-5 = 0.000012

特殊值

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Printf("正无穷: %v\n", math.Inf(1))
    fmt.Printf("负无穷: %v\n", math.Inf(-1))
    fmt.Printf("非数: %v\n", math.NaN())
}

复数类型

Go 原生支持复数:

类型说明
complex64实部和虚部都是 float32
complex128实部和虚部都是 float64(推荐)

示例

package main

import (
    "fmt"
    "math/cmplx"
)

func main() {
    var c1 complex64 = 3 + 4i
    var c2 complex128 = complex(3, 4)

    fmt.Printf("c1: %v\n", c1)
    fmt.Printf("c2: %v\n", c2)
    fmt.Printf("实部: %v\n", real(c2))
    fmt.Printf("虚部: %v\n", imag(c2))
    fmt.Printf("模: %v\n", cmplx.Abs(c2))
}

输出:

c1: (3+4i)
c2: (3+4i)
实部: 3
虚部: 4
模: 5

字符串类型

字符串是不可变的字节序列,通常用于存储文本。

声明字符串

package main

import "fmt"

func main() {
    var s1 string = "Hello"
    s2 := "世界"

    fmt.Println(s1)
    fmt.Println(s2)
}

字符串长度

package main

import "fmt"

func main() {
    s := "Hello, 世界"

    fmt.Printf("字节数: %d\n", len(s))
    fmt.Printf("字符数: %d\n", len([]rune(s)))
}

输出:

字节数: 13
字符数: 9

字符串操作

package main

import (
    "fmt"
    "strings"
)

func main() {
    s := "Hello, World!"

    fmt.Printf("包含 World: %v\n", strings.Contains(s, "World"))
    fmt.Printf("前缀 Hello: %v\n", strings.HasPrefix(s, "Hello"))
    fmt.Printf("后缀 !: %v\n", strings.HasSuffix(s, "!"))
    fmt.Printf("索引: %d\n", strings.Index(s, "World"))
    fmt.Printf("替换: %s\n", strings.Replace(s, "World", "Go", 1))
    fmt.Printf("小写: %s\n", strings.ToLower(s))
    fmt.Printf("大写: %s\n", strings.ToUpper(s))
    fmt.Printf("分割: %v\n", strings.Split(s, ", "))
}

字符串拼接

package main

import (
    "fmt"
    "strings"
)

func main() {
    s1 := "Hello" + " " + "World"
    fmt.Println(s1)

    parts := []string{"Hello", "World"}
    s2 := strings.Join(parts, " ")
    fmt.Println(s2)

    fmt.Sprintf("%s %s", "Hello", "World")
}

多行字符串

使用反引号定义多行字符串:

package main

import "fmt"

func main() {
    s := `第一行
第二行
第三行`

    fmt.Println(s)
}

遍历字符串

package main

import "fmt"

func main() {
    s := "Hello, 世界"

    fmt.Println("按字节遍历:")
    for i := 0; i < len(s); i++ {
        fmt.Printf("%d: %c\n", i, s[i])
    }

    fmt.Println("\n按字符遍历:")
    for i, r := range s {
        fmt.Printf("%d: %c\n", i, r)
    }
}

字符串不可变

字符串是不可变的,不能修改:

s := "Hello"
s[0] = 'h'

如果需要修改,转换为字节切片:

package main

import "fmt"

func main() {
    s := "Hello"
    b := []byte(s)
    b[0] = 'h'
    s = string(b)
    fmt.Println(s)
}

输出:

hello

类型转换

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

数值类型转换

package main

import "fmt"

func main() {
    var i int = 100
    var f float64 = float64(i)
    var u uint = uint(i)

    fmt.Printf("int: %d\n", i)
    fmt.Printf("float64: %f\n", f)
    fmt.Printf("uint: %d\n", u)
}

字符串与数值转换

使用 strconv 包:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, _ := strconv.Atoi("123")
    fmt.Printf("字符串转整数: %d\n", i)

    s := strconv.Itoa(123)
    fmt.Printf("整数转字符串: %s\n", s)

    f, _ := strconv.ParseFloat("3.14", 64)
    fmt.Printf("字符串转浮点数: %f\n", f)

    b, _ := strconv.ParseBool("true")
    fmt.Printf("字符串转布尔: %t\n", b)

    s2 := strconv.FormatFloat(3.14, 'f', 2, 64)
    fmt.Printf("浮点数转字符串: %s\n", s2)
}

类型推断

使用 := 声明变量时,Go 会自动推断类型:

package main

import "fmt"

func main() {
    i := 100
    f := 3.14
    s := "Hello"
    b := true

    fmt.Printf("i 的类型: %T\n", i)
    fmt.Printf("f 的类型: %T\n", f)
    fmt.Printf("s 的类型: %T\n", s)
    fmt.Printf("b 的类型: %T\n", b)
}

输出:

i 的类型: int
f 的类型: float64
s 的类型: string
b 的类型: bool

总结

本章学习了 Go 语言的数据类型:

类型分类具体类型
布尔bool
整数int, int8, int16, int32, int64, uint, byte, rune
浮点float32, float64
复数complex64, complex128
字符串string