package main import "fmt" // 1. 定义结构体类型:把不同类型的相关数据组合在一起。 // type 表示定义类型,Student 是类型名,Name / Age / Score 是字段。 type Student struct { Name string Age int Score float64 } // 2. 结构体也可以作为普通函数的参数。 // 这里传入的是 Student 值的副本;本函数只读取它。 func printStudent(student Student) { fmt.Printf("姓名:%s,年龄:%d,成绩:%.1f\n", student.Name, student.Age, student.Score) } func main() { // 3. 使用字段名初始化。多行写法的最后一个字段也需要逗号。 fmt.Println("=== 创建与访问字段 ===") student := Student{ Name: "小朱", Age: 20, Score: 90.5, } printStudent(student) student.Age = 21 fmt.Printf("修改后的年龄:%d\n", student.Age) // 4. 没有显式赋值的字段会得到各自类型的零值。 fmt.Println("\n=== 结构体零值 ===") var empty Student fmt.Printf("姓名:%q,年龄:%d,成绩:%.1f\n", empty.Name, empty.Age, empty.Score) // 5. 本课结构体只包含 string / int / float64,赋值后修改副本不影响原值。 fmt.Println("\n=== 结构体赋值 ===") copied := student copied.Name = "小李" fmt.Printf("原姓名:%s,副本姓名:%s\n", student.Name, copied.Name) // 6. []Student 是结构体切片,每个元素保存一名学生的信息。 fmt.Println("\n=== 结构体切片 ===") students := []Student{ {Name: "小朱", Age: 21, Score: 90.5}, {Name: "小李", Age: 19, Score: 80}, {Name: "小陈", Age: 22, Score: 75.5}, } total := 0.0 for _, item := range students { printStudent(item) total += item.Score } fmt.Printf("总分:%.1f,平均分:%.2f\n", total, total/float64(len(students))) // 7. range 得到的 item 是元素副本。要修改原元素,使用索引。 for index := range students { students[index].Age++ } fmt.Printf("所有学生年龄加一后,第一位年龄:%d\n", students[0].Age) // 8. 不单独起类型名的结构体切片:对应上一课测试中的 []struct。 // 本课先把它当作“由多条记录组成的表”,只用普通循环读取。 fmt.Println("\n=== 理解测试数据表 ===") tests := []struct { name string a int b int want int }{ {name: "正数相加", a: 2, b: 3, want: 5}, {name: "正负相加", a: -2, b: 3, want: 1}, } for _, tt := range tests { got := tt.a + tt.b fmt.Printf("%s:实际=%d,期望=%d,通过=%t\n", tt.name, got, tt.want, got == tt.want) } }