golang:方法接收者带星号和不带星号的区别

一,说明:

  • 不带星号的方法‌:这些方法定义在值接收者(value receiver)上。
    当你调用这些方法时,会操作该值的副本。
    如果方法内部修改了接收者,这些修改不会反映到原始值上。

  • 带星号的方法‌:这些方法定义在指针接收者(pointer receiver)上。
    当你调用这些方法时,会操作原始值的指针。
    如果方法内部修改了接收者指向的值,这些修改会反映到原始值上。

 

二,代码:

package main

import (
    "fmt"
    "reflect"
)

func isPointer(v interface{}) bool {
    return reflect.ValueOf(v).Kind() == reflect.Ptr
}

// 定义一个结构体
type Person struct {
    Name string
    Age  int
}


// 定义一个带星号的方法(指针接收者)
func (p *Person) IncrementAge() {
    fmt.Printf("星号方法中 p是否指针: %v\n", isPointer(p))
    fmt.Printf("星号方法中 p的地址:%p\n", &p)
    fmt.Printf("星号方法中 p指向的地址:%p\n", &*p)
    p.Age++
}

// 定义一个不带星号的方法(值接收者)
func (p Person) PrintAge() {
    fmt.Printf("方法1中 p是否指针: %v\n", isPointer(p))
    fmt.Printf("方法1中 p的地址:%p\n", &p)
    fmt.Println("方法1改变前:",p.Age)         // 输出:31
    p.Age++     //此时的p是一个副本,修改后不会影响调用它的对象
    fmt.Println("方法1改变后:",p.Age)          // 输出:32
}


// 定义一个不带星号的方法2(值接收者)
func (p Person) PrintAge2() {
    fmt.Printf("方法2中 p是否指针: %v\n", isPointer(p))
    fmt.Printf("方法2中 p的地址:%p\n", &p)
    fmt.Println("方法2改变前:",p.Age)       // 输出:31
    p.Age+=5     //此时的p是一个副本,修改后不会影响调用它的对象
    fmt.Println("方法2改变后:",p.Age)      // 输出:36
}


func main() {
    person := Person{Name: "Alice", Age: 30}
    fmt.Printf("person对象的地址:%p\n", &person)
    fmt.Println("星号方法调用前:",person.Age) // 输出:31
    person.IncrementAge() // 调用带星号方法
    fmt.Println("星号方法调用后:",person.Age) // 输出:31


    (&person).IncrementAge() // 调用带星号方法2
    fmt.Println("星号方法调用后2:",person.Age) // 输出:31

    person.PrintAge()
    fmt.Println("person.Age:",person.Age) // 输出:31

    person.PrintAge2()
    fmt.Println("person.Age:",person.Age) // 输出:31
}

 

三,测试效果:

$ go run main.go 
person对象的地址:0xc00009c000
星号方法调用前: 30
星号方法中 p是否指针: true
星号方法中 p的地址:0xc000088040
星号方法中 p指向的地址:0xc00009c000
星号方法调用后: 31
星号方法中 p是否指针: true
星号方法中 p的地址:0xc000088048
星号方法中 p指向的地址:0xc00009c000
星号方法调用后2: 32
方法1中 p是否指针: false
方法1中 p的地址:0xc00009c018
方法1改变前: 32
方法1改变后: 33
person.Age: 32
方法2中 p是否指针: false
方法2中 p的地址:0xc00009c030
方法2改变前: 32
方法2改变后: 37
person.Age: 32

 

posted @ 2024-12-14 13:05  刘宏缔的架构森林  阅读(29)  评论(0编辑  收藏  举报