golang 值方法和指针方法

一段示例代码

package main

type info struct {
	Name string
	Hp   uint32
	Mp   uint32
}

// 值方法
func (my info) PrintName() {
	println(my.Name)
	println(my.Name)
}

// 指针方法
func (my *info) PrintName2() {
	println(my.Name)
	println(my.Name)
}

func main() {
	var i = info{
		Name: "abc",
		Hp:   1,
		Mp:   2,
	}

	(&i).PrintName2()
	i.PrintName()
}

如果你需要在方法中修改接收者,则必须使用指针方法。因为值方法是拷贝的一份副本


debug

# dlv debug .

在28行打个断点
(dlv) b main.go:28
Breakpoint 1 set at 0x45b6a7 for main.main() ./main.go:28


执行到下一个断点
(dlv) c
> main.main() ./main.go:28 (hits goroutine(1):1 total:1) (PC: 0x45b6a7)
    23:                 Name: "abc",
    24:                 Hp:   1,
    25:                 Mp:   2,
    26:         }
    27:
=>  28:         (&i).PrintName2()
    29:         i.PrintName()
    30: }

查看i的地址
(dlv) print &i
(*main.info)(0xc00004e758)


查看指针下的数据: 0x0000000000467a10 Name的数据地址, 0x0000000000000003 Name的长度, 0x0000000200000001 四字节的Hp和Mp
(dlv) x -len 3 -size 8 -x 0xc00004e758
0xc00004e758:   0x0000000000467a10   0x0000000000000003   0x0000000200000001 

查看Name的数据
(dlv) x -len 3 -x 0x0000000000467a10
0x467a10:   0x61   0x62   0x63

三次步进到 PrintName2 函数
(dlv) s
(dlv) s
(dlv) s
(dlv) ls
> main.(*info).PrintName2() ./main.go:18 (PC: 0x45b5ef)
    13: }
    14:
    15: // 指针方法
    16: func (my *info) PrintName2() {
    17:         println(my.Name)
=>  18:         println(my.Name)
    19: }
    20:
    21: func main() {
    22:         var i = info{
    23:                 Name: "abc",


查看 my 的地址
(dlv) print &my
(**main.info)(0xc00004e740)


查看 my 地址下的数据 0x000000c00004e758 是指向 i 数据的指针
(dlv) x -len 2 -size 8 0xc00004e740
0xc00004e740:   0x000000c00004e758   0x000000c00004e701


跳出函数
(dlv) so
abc
> main.main() ./main.go:29 (PC: 0x45b6b1)
Values returned:

    24:                 Hp:   1,
    25:                 Mp:   2,
    26:         }
    27:
    28:         (&i).PrintName2()
=>  29:         i.PrintName()
    30: }


三次步进到 PrintName 函数
(dlv) s
(dlv) s
(dlv) s
(dlv) ls
> main.info.PrintName() ./main.go:12 (PC: 0x45b51e)
     7: }
     8:
     9: // 值方法
    10: func (my info) PrintName() {
    11:         println(my.Name)
=>  12:         println(my.Name)
    13: }
    14:
    15: // 指针方法
    16: func (my *info) PrintName2() {
    17:         println(my.Name)

查看 my 的地址
(dlv) print &my
(*main.info)(0xc00004e740)

查看 my 地址下的数据,数据被拷贝了一份在这里
(dlv) x -len 3 -size 8 -x 0xc00004e740
0xc00004e740:   0x0000000000467a10   0x0000000000000003   0x0000000200000001


退出调试
(dlv) exit
posted @ 2022-11-23 21:52  Ajanuw  阅读(93)  评论(0编辑  收藏  举报