Golang 数据类型详解
复合数据类型
数组(Array)
数组是固定长度的相同类型元素序列。
go
package main
import "fmt"
func arrayDemo() {
// 声明数组
var arr1 [5]int
arr1[0] = 1
arr1[1] = 2
// 初始化数组
arr2 := [5]int{1, 2, 3, 4, 5}
// 自动推断长度
arr3 := [...]int{1, 2, 3, 4, 5, 6}
// 指定索引初始化
arr4 := [5]int{0: 10, 2: 20, 4: 40}
fmt.Println("arr1:", arr1)
fmt.Println("arr2:", arr2)
fmt.Println("arr3:", arr3)
fmt.Println("arr4:", arr4)
fmt.Println("数组长度:", len(arr2))
}切片(Slice)
切片是动态数组,是对数组的抽象。
go
func sliceDemo() {
// 创建切片
slice1 := []int{1, 2, 3, 4, 5}
// 使用 make 创建切片
slice2 := make([]int, 5) // 长度为5
slice3 := make([]int, 5, 10) // 长度5,容量10
// 切片操作
slice4 := slice1[1:4] // [2, 3, 4]
slice5 := slice1[:3] // [1, 2, 3]
slice6 := slice1[2:] // [3, 4, 5]
fmt.Println("slice1:", slice1)
fmt.Println("slice4:", slice4)
fmt.Printf("长度: %d, 容量: %d\n", len(slice3), cap(slice3))
// 追加元素
slice1 = append(slice1, 6, 7, 8)
fmt.Println("追加后:", slice1)
// 复制切片
slice7 := make([]int, len(slice1))
copy(slice7, slice1)
fmt.Println("复制的切片:", slice7)
}映射(Map)
Map 是无序的键值对集合。
go
func mapDemo() {
// 创建 map
map1 := make(map[string]int)
map1["apple"] = 5
map1["banana"] = 3
map1["orange"] = 7
// 字面量初始化
map2 := map[string]string{
"name": "Jackson",
"city": "Beijing",
"job": "Engineer",
}
// 访问元素
fmt.Println("apple数量:", map1["apple"])
// 检查键是否存在
value, exists := map1["grape"]
if exists {
fmt.Println("grape数量:", value)
} else {
fmt.Println("grape不存在")
}
// 删除元素
delete(map1, "banana")
// 遍历 map
fmt.Println("\n遍历 map2:")
for key, value := range map2 {
fmt.Printf("%s: %s\n", key, value)
}
fmt.Println("map1长度:", len(map1))
}结构体(Struct)
结构体是字段的集合。
go
// 定义结构体
type Person struct {
Name string
Age int
Email string
Address string
}
func structDemo() {
// 创建结构体实例
person1 := Person{
Name: "Jackson",
Age: 25,
Email: "jackson@example.com",
Address: "Beijing",
}
// 简短声明
person2 := Person{"Alice", 30, "alice@example.com", "Shanghai"}
// 部分字段初始化
person3 := Person{Name: "Bob", Age: 28}
// 访问字段
fmt.Println("姓名:", person1.Name)
fmt.Println("年龄:", person1.Age)
// 修改字段
person1.Age = 26
fmt.Println("修改后年龄:", person1.Age)
// 匿名结构体
employee := struct {
Name string
Salary float64
}{
Name: "Tom",
Salary: 50000.0,
}
fmt.Printf("员工: %+v\n", employee)
fmt.Printf("person2: %+v\n", person2)
fmt.Printf("person3: %+v\n", person3)
}指针(Pointer)
指针存储变量的内存地址。
go
func pointerDemo() {
// 基本指针操作
x := 10
p := &x // 获取 x 的地址
fmt.Println("x的值:", x)
fmt.Println("x的地址:", p)
fmt.Println("指针指向的值:", *p)
// 通过指针修改值
*p = 20
fmt.Println("修改后x的值:", x)
// 结构体指针
person := &Person{
Name: "Jackson",
Age: 25,
}
// 可以直接访问字段,Go会自动解引用
fmt.Println("姓名:", person.Name)
person.Age = 26
fmt.Println("年龄:", person.Age)
// new 函数创建指针
ptr := new(int)
*ptr = 100
fmt.Println("new创建的指针值:", *ptr)
}接口(Interface)
接口定义对象的行为。
go
// 定义接口
type Shape interface {
Area() float64
Perimeter() float64
}
// 矩形
type Rectangle struct {
Width float64
Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
// 圆形
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * 3.14159 * c.Radius
}
func interfaceDemo() {
var s Shape
// Rectangle 实现了 Shape 接口
s = Rectangle{Width: 10, Height: 5}
fmt.Printf("矩形面积: %.2f\n", s.Area())
fmt.Printf("矩形周长: %.2f\n", s.Perimeter())
// Circle 也实现了 Shape 接口
s = Circle{Radius: 7}
fmt.Printf("圆形面积: %.2f\n", s.Area())
fmt.Printf("圆形周长: %.2f\n", s.Perimeter())
// 空接口
var any interface{}
any = 42
fmt.Println("空接口存储int:", any)
any = "Hello"
fmt.Println("空接口存储string:", any)
}类型断言与类型转换
go
func typeAssertionDemo() {
var i interface{} = "Hello, World"
// 类型断言
s, ok := i.(string)
if ok {
fmt.Println("字符串值:", s)
}
// 类型判断
switch v := i.(type) {
case int:
fmt.Println("整数:", v)
case string:
fmt.Println("字符串:", v)
case bool:
fmt.Println("布尔:", v)
default:
fmt.Println("未知类型")
}
}完整示例
go
package main
import "fmt"
type Student struct {
Name string
Age int
Scores []int
}
func (s Student) Average() float64 {
if len(s.Scores) == 0 {
return 0
}
sum := 0
for _, score := range s.Scores {
sum += score
}
return float64(sum) / float64(len(s.Scores))
}
func main() {
// 创建学生映射
students := make(map[string]Student)
students["001"] = Student{
Name: "张三",
Age: 20,
Scores: []int{85, 90, 88, 92},
}
students["002"] = Student{
Name: "李四",
Age: 21,
Scores: []int{78, 82, 85, 80},
}
// 遍历学生信息
fmt.Println("=== 学生成绩单 ===")
for id, student := range students {
fmt.Printf("\n学号: %s\n", id)
fmt.Printf("姓名: %s\n", student.Name)
fmt.Printf("年龄: %d\n", student.Age)
fmt.Printf("成绩: %v\n", student.Scores)
fmt.Printf("平均分: %.2f\n", student.Average())
}
}运行结果
=== 学生成绩单 ===
学号: 001
姓名: 张三
年龄: 20
成绩: [85 90 88 92]
平均分: 88.75
学号: 002
姓名: 李四
年龄: 21
成绩: [78 82 85 80]
平均分: 81.25小结
- 数组:固定长度,类型相同
- 切片:动态数组,灵活方便
- Map:键值对集合,无序
- 结构体:自定义复合类型
- 指针:存储变量地址,高效传递
- 接口:定义行为规范,实现多态