package main
import (
"fmt"
)
//T是M1接受者,不是实现M2接受者
//*T是M1接受者,也是M2的接受者
//所以T对象不可以赋值给接口对象。*T可以
//结论:
// 1.结构T实现接口I时,如果想通过方法改变其属性,则需要*T实现I所有方法:
// 2.嵌套结构时,编译器会将子结构的属性和方法拷贝给父结构,与子结构无关系了;
// 3.赋值给接口对象I1,或者接口作为函数参数时,I1:=&T,因为是*T实现了接口I,否则报错
type T struct {
Name string
}
func (t T) M1(name string) {
// 值传递,改变副本的值
t.Name = name
}
func (t *T) M2(name string) {
// 结构体指针,修改其本身
t.Name = name
}
type Intf interface {
M1(name string)
M2(name string)
}
func main() {
fmt.Println(`*****t1 := T{"t1"}`)
t1 := T{"t1"}
fmt.Println("M1之前:", t1.Name)
t1.M1("name1")
fmt.Println("M1之后:", t1.Name)
t1.M2("name2")
fmt.Println("M2之后:", t1.Name)
fmt.Println(`*****t2 := &T{"t2"}`)
t2 := &T{"t2"}
fmt.Println("M1之前:", t2.Name)
t2.M1("name1")
fmt.Println("M1之后:", t2.Name)
t2.M2("name2")
fmt.Println("M2之后:", t2.Name)
// T does not implement Intf (M2 method has pointer receiver)
// var t3 Intf = t1
var t3 Intf = &t1
t1.Name = "t1"
fmt.Println(`****t3 Intf = &t1`)
fmt.Println("M1之前:", t1.Name)
t3.M1("name1")
fmt.Println("M1之后:", t1.Name)
t3.M2("name2")
fmt.Println("M2之后:", t1.Name)
t1.Name = "t0"
fmt.Println("test1 before", t1.Name)
test1(&t1)
fmt.Println("test1 after", t1.Name)
test2(&t1)
fmt.Println("test2 after", t1.Name)
// 只有*S实现I,且使用接口作为函数的参数时,需要传递&T,才能改变自身数据
t1.Name = "h1"
test3(t1)
fmt.Println(t1.Name)
t1.Name = "h1"
test4(&t1)
fmt.Println(t1.Name)
//嵌套类型
// 就是复制一份给新的结构,与原结构无关了
t1.Name = "t1"
type S struct {
T
age int
}
s1 := S{T: t1, age: 12}
fmt.Println(s1.Name, t1.Name)
s1.M1("s1")
fmt.Println(s1.Name, t1.Name)
s1.M2("s2")
fmt.Println(s1.Name, t1.Name)
//新结构与接口
var I1 Intf = &s1
}
func test1(t Intf) {
t.M1("n1")
}
func test2(t Intf) {
t.M2("n2")
}
func test3(t T) {
t.M2("m1")
}
func test4(t *T) {
t.M2("m2")
}