| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- package main
- import "fmt"
- type Student struct {
- Name string
- Age int
- Score float64
- }
- // 1. 普通函数:学生作为普通参数传入。
- func describe(student Student) string {
- return fmt.Sprintf("%s,年龄:%d,成绩:%.1f", student.Name, student.Age, student.Score)
- }
- // 2. 方法:func 后面的 (student Student) 称为接收者。
- // 值接收者接收 Student 值的副本,这个方法只读取字段。
- func (student Student) Summary() string {
- return fmt.Sprintf("%s,年龄:%d,成绩:%.1f", student.Name, student.Age, student.Score)
- }
- // 3. 值接收者中修改整数,只修改副本,不改变原学生。
- func (student Student) TryBirthday() {
- student.Age++
- }
- // 4. 指针接收者可以通过指针修改原学生。
- // 本方法约定允许 nil,返回 false 表示没有可修改的学生。
- func (student *Student) Birthday() bool {
- if student == nil {
- return false
- }
- student.Age++
- return true
- }
- // 5. 方法也能接收普通参数,并通过返回值报告是否成功。
- func (student *Student) SetScore(score float64) bool {
- // 这种写法同时拒绝不在范围内的值和 NaN。
- if student == nil || !(score >= 0 && score <= 100) {
- return false
- }
- student.Score = score
- return true
- }
- func main() {
- student := Student{Name: "小朱", Age: 20, Score: 85}
- fmt.Println("=== 普通函数与方法 ===")
- fmt.Println("普通函数:", describe(student))
- fmt.Println("方法调用:", student.Summary())
- fmt.Println("\n=== 值接收者 ===")
- student.TryBirthday()
- fmt.Printf("调用 TryBirthday 后,原年龄:%d\n", student.Age)
- fmt.Println("\n=== 指针接收者 ===")
- // student 是可以取地址的变量,Go 自动把调用理解为 (&student).Birthday()。
- ok := student.Birthday()
- fmt.Printf("调用 Birthday 后,年龄:%d,成功:%t\n", student.Age, ok)
- fmt.Println("\n=== 方法参数与返回值 ===")
- ok = student.SetScore(95)
- fmt.Printf("设置 95 分:成功=%t,当前成绩=%.1f\n", ok, student.Score)
- ok = student.SetScore(120)
- fmt.Printf("设置 120 分:成功=%t,当前成绩=%.1f\n", ok, student.Score)
- fmt.Println("\n=== 通过指针调用方法 ===")
- pointer := &student
- // *Student 也可以调用值接收者的方法,前提是这里指针非 nil。
- fmt.Println(pointer.Summary())
- fmt.Println("\n=== nil 指针接收者 ===")
- var empty *Student
- fmt.Printf("nil 调用 Birthday:%t\n", empty.Birthday())
- fmt.Printf("nil 调用 SetScore:%t\n", empty.SetScore(80))
- // empty.Summary() 不能安全调用:值接收者需要取得 Student 值。
- }
|