struct

struct 嵌入 struct

可以起到类似于继承的作用,但不是真正的继承,参考

struct内嵌匿名属性使用值类型和指针类型的区别?

内嵌值类型,给内嵌变量赋值时底层是创建了一个新的对象,发生的是值拷贝。

指针类型,发生的也是值拷贝,但拷贝的是指针,因此底层对象是同一个。

type user struct {
	name  string
	email string
}

func (u *user) notify() {
	fmt.Printf("Send email to %s@<%s>\n", u.name, u.email)
}

func (u *user) setName(n string) {
	u.name = n
}

type admin struct {
	user         //设置内部类型
	level string //外部类新增的属性
}

// 覆盖内部类的方法
func (a *admin) notify() {
	fmt.Printf("Send admin email to %s@<%s>\n", a.name, a.email)
}

type operator struct {
	*user //指针形式内部类
	level string
}

func TestName(t *testing.T) {
	u1 := user{"zhangsan", "[email protected]"}
	u2 := user{"lisi", "[email protected]"}
	a := admin{
		user:  u1,
		level: "high",
	}
	o := operator{
		user:  &u2, // 指针变量
		level: "middle",
	}
	a.user.notify() //既可以通过内部类型调用方法。内部类的属性和方法始终可以通过内部类名进行访问
	a.notify()      //也可以直接通过外部类的对象访问,此时内部类型user的notify()就被覆盖了,触发的是admin.notify()
	a.setName("zhangsan1")
	o.setName("lisi1")
	fmt.Println(a.name, a.user.name, o.name, o.user.name) 
	fmt.Println(u1.name, u2.name)  // u1.name 没有被修改,因为u1传给admin的操作是发生了值拷贝,而u2传递的是指针,所以拷贝的也是指针,修改是同一个底层对象
}

struct 嵌入 interface(struct+interface实现虚基类)

type Model interface {
    Persist(context context.Context, msg interface{}) bool
}
type ModelImpl struct{}
func (m ModelImpl) Persist(context context.Context, msgIface interface{}) bool {
// 具体实现省略
}
type Service struct {
	model Model  // 内嵌interface,传入Service的Model类型ModelImpl就必须要实现Model接口
}

var serviceImpl = Service{
    Model:  ModelImpl,
}  // 这样,初始化的Service实例serviceImpl就可以给外部调用了,可以直接调用Model接口的方法

这样做的好处:

  1. Service可以有多个不同的ModelImpl实体,多态,灵活。

  2. 限制了ModelImpl必须要实现Model接口指定的方法。

Last updated

Was this helpful?