Golang做继承的时候,会有结构体嵌套,出现了两种定义的写法:

type Animal struct {//父类
	name string
}
type Dog struct {//子类
	Feet int8
	Animal		//父类结构体
}
type DogWithInnerPointer struct {//子类
	Feet int8
	*Animal		//父类结构体的指针
}

        差异在于在 对象值传递的时候 方法内 对象字段的修改:

                如果是普通字段,函数体内修改不会对原对象有影响;

                如果是指针字段,则会影响原对象的字段。

func main() {

	d := &Dog{
		Feet: 4,
		Animal: Animal{
			name: "改名前",
		},
	}
	d2 := &DogWithInnerPointer{
		Feet: 4,
		Animal: &Animal{ //注意嵌套的是结构体指针
			name: "改名前",
		},
	}
	d2.getName()
	d.getName()
	fmt.Println(d.Feet)
	fmt.Println(d2.Feet)

	dog1Field(*d)
	dog2Field(*d2)

	d.getName()
	d2.getName()
	fmt.Println(d.Feet)
	fmt.Println(d2.Feet)
}
func dog1Field(dog Dog) {
	dog.name = "改名后"
	dog.Feet = 23
}
func dog2Field(dog DogWithInnerPointer) {
	dog.name = "改名后"
	dog.Feet = 23
}

        注意看到最后两个函数接受的是对象的副本!

结果如下,关键看 结果的5、6行。

Animal的名字是改名前
Animal的名字是改名前
4                   
4                   
Animal的名字是改名前
Animal的名字是改名后
4                   
4      

        但是如果函数是传指针的话,结果又不一样了。

        同样的重点看最后两个函数的形参!

func main() {

	d := &Dog{
		Feet: 4,
		Animal: Animal{
			name: "改名前",
		},
	}
	d2 := &DogWithInnerPointer{
		Feet: 4,
		Animal: &Animal{ //注意嵌套的是结构体指针
			name: "改名前",
		},
	}
	d2.getName()
	d.getName()
	fmt.Println(d.Feet)
	fmt.Println(d2.Feet)

	dog1Field(d)
	dog2Field(d2)

	d.getName()
	d2.getName()
	fmt.Println(d.Feet)
	fmt.Println(d2.Feet)
}
func dog1Field(dog *Dog) {
	dog.name = "改名后"
	dog.Feet = 23
}
func dog2Field(dog *DogWithInnerPointer) {
	dog.name = "改名后"
	dog.Feet = 23
}

函数的形参是指针的话,不论字段是不同字段,还是指针字段,都会对原对象做出修改。

结果如下:

Animal的名字是改名前
Animal的名字是改名前
4                   
4                   
Animal的名字是改名后
Animal的名字是改名后
23                  
23  

总结:

        函数 值传递的时候 是将对象拷贝一份传入函数体内,对象的普通字段,和指针字段也是副本,所以修改  普通字段的副本不会对原对象字段有影响,而修改指针对象的副本所指向的地址中的值却会对原对象有影响。归根结底是指针和指针的副本指向的都是同一块地址

        而当函数是引用传递的时候(传对象的指针),修改的就是原对象本身了。因为这个指针指向的就是原对象的地址。