数据类型是编程语言的基础。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
布尔类型只有两个值:true 和 false。
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
falsevar b bool = true
var i int = int(b)
Go 提供了多种整数类型,分为有符号和无符号两类。
| 类型 | 大小 | 范围 |
|---|---|---|
int8 | 1 字节 | -128 ~ 127 |
int16 | 2 字节 | -32768 ~ 32767 |
int32 | 4 字节 | -2147483648 ~ 2147483647 |
int64 | 8 字节 | -9223372036854775808 ~ 9223372036854775807 |
int | 平台相关 | 32 位系统为 int32,64 位系统为 int64 |
| 类型 | 大小 | 范围 |
|---|---|---|
uint8 | 1 字节 | 0 ~ 255 |
uint16 | 2 字节 | 0 ~ 65535 |
uint32 | 4 字节 | 0 ~ 4294967295 |
uint64 | 8 字节 | 0 ~ 18446744073709551615 |
uint | 平台相关 | 32 位系统为 uint32,64 位系统为 uint64 |
| 类型 | 说明 |
|---|---|
byte | uint8 的别名,常用于处理字节数据 |
rune | int32 的别名,常用于处理 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 提供了两种浮点数类型:float32 和 float64。
| 类型 | 大小 | 精度 |
|---|---|---|
float32 | 4 字节 | 约 7 位小数 |
float64 | 8 字节 | 约 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 |