Golang编程基础: 结构体定义结构体指针类型方法 和 结构体类型方法的区别

type Test struct {
	integer int
	pInteger *int
}

func (t Test) PrintValue() {
	fmt.Print("Integer[v, addr]:  ", t.integer, &t.integer)
	if nil != t.pInteger {
		fmt.Println("; PInteger[v, pInteger, addr]:  ", *t.pInteger, t.pInteger, &t.pInteger)
	} else {
		fmt.Println()
	}
}


func (t Test) setValue(v int) {
	t.integer = v
	if nil == t.pInteger {
		fmt.Println("setValue New PInteger")
		t.pInteger = new(int)
	}
	*t.pInteger = v
}

func (t *Test) pSetValue(v int) {
	t.integer = v
	if nil == t.pInteger {
		fmt.Println("pSetValue New PInteger")
		t.pInteger = new(int)
	}
	*t.pInteger = v
}

func main() {
	var test = Test{}

	test.setValue(100)
	/* 对比两次打印出来的 值 参数地址 */
	test.PrintValue()
	test.PrintValue()

	test.pSetValue(1000)
	/* 对比两次打印的值 和 integer的地址, pInteger的地址 */
	test.PrintValue()
	test.PrintValue()
}

/*
setValue New PInteger // 已经将pinteger进行了初始化
/* 下面两次打印 1. 并未将pinteger打印出来; 2. integer值未改变; 3. integer地址两次打印不同 */
Integer[v, addr]:  0 0xc00003c1f0
Integer[v, addr]:  0 0xc00003c200


pSetValue New PInteger// 已经将pinteger进行了初始化
/* 下面两次打印 1. 将pinteger打印出来;  1. pinteger指针一样; 2. integer值改变; 3. integer地址两次打印不同 */
Integer[v, addr]:  1000 0xc00003c210; PInteger[v, pInteger, addr]:   1000 0xc0000180d8 0xc00003c210
Integer[v, addr]:  1000 0xc00003c220; PInteger[v, pInteger, addr]:   1000 0xc0000180d8 0xc00003c220
*/

基于上面的试验, 得出假设

1. 非指针结构体定义的方法是对 结构体的拷贝, 而不是直接饮用;

2. 如果想在拷贝中改变原本结构体存放的值, 那 原先结构体存放值的变量类型是指针类型;

为了验证 , 将打印改成 结构体指针类型方法,再进行输出, 如果地址不变,则成立

验证方式:

(1) 原指针打印

(2) 结构体指针方法调用

func (t *Test) PPrintValue() {
	fmt.Print("Integer[v, addr]:  ", t.integer, &t.integer)
	if nil != t.pInteger {
		fmt.Println("; PInteger[v, pInteger, addr]:  ", *t.pInteger, t.pInteger, &t.pInteger)
	} else {
		fmt.Println()
	}
}

func main() {
	var test = Test{}
	test.setValue(100)
	/* 对比两次打印出来的 值 参数地址 */
	test.PPrintValue()
	test.PPrintValue()
	fmt.Println("原始指针_1[integer_addr, pinteger_addr]: ", &test.integer, &test.pInteger)


	test.pSetValue(1000)
	/* 对比两次打印的值 和 integer的地址, pInteger的地址 */
	test.PPrintValue()
	test.PPrintValue()
	fmt.Println("原始指针_2[integer_addr, pinteger_addr]: ", &test.integer, &test.pInteger)

}
/*
setValue New PInteger
Integer[v, addr]:  0 0xc00003c1f0
Integer[v, addr]:  0 0xc00003c1f0
原始指针_1[integer, pinteger]:  0xc00003c1f0 0xc00003c1f8


pSetValue New PInteger
Integer[v, addr]:  1000 0xc00003c1f0; PInteger[v, pInteger, addr]:   1000 0xc000
0180d8 0xc00003c1f8
Integer[v, addr]:  1000 0xc00003c1f0; PInteger[v, pInteger, addr]:   1000 0xc000
0180d8 0xc00003c1f8
原始指针_2[integer, pinteger]:  0xc00003c1f0 0xc00003c1f8

*/

结论

    1. 非结构体指针类型 操作的是 结构体的备份;

    2. 非结构体能够改变的是已经初始化好的 原结构体指针类型变量的值;

猜你喜欢

转载自blog.csdn.net/halo_hsuh/article/details/107222057