golang中值类型的嵌入式字段和指针类型的嵌入式字段

总结:

  1. 值类型的嵌入式字段,该类型拥有值类型的方法集,没有值指针类型的方法集

  2. 指针类型的嵌入式字段,该类型拥有值指针类型的方法集,没有值类型的方法集,并且,该类型的指针类型也有值指针类型的方法集

有点绕,见案例:

package main

import "fmt"

type Boss struct{}
func (b *Boss) AssignWork() {
	fmt.Println("Boss assigned work")
}

type Manager struct{}
func (m *Manager) PreparePowerPoint() {
	fmt.Println("PowerPoint prepared")
}

type BossManager struct {
	Boss  // 嵌入式字段
	Manager  // 嵌入式字段
}
type BossManagerUsingPointers struct {
	*Boss  // 指针类型的嵌入式字段
	*Manager  // 指针类型的嵌入式字段
}
/*
BossManager和BossManagerUsingPointers的区别?
BossManage类型没有实现这个PromotionMaterial接口,BossManage的指针类型实现了这个接口
BossManagerUsingPointers类型实现了PromotionMaterial这个接口
BossManagerUsingPointers的指针类型也是PromotionMaterial这个接口类型
*/

// Define an interface that requires both methods.
type PromotionMaterial interface {
	AssignWork()
	PreparePowerPoint()
}

func promote(pm PromotionMaterial) {
	fmt.Println("Promoted a person with promise.")
}

func main() {
	bm := BossManager{}

	// Both methods (which use pointer receivers) have been promoted to BossManager.
	bm.AssignWork()        // "Boss assigned work"
	bm.PreparePowerPoint() // "PowerPoint prepared"

	// However, the method set of BossManager does not include either method because:
	// 1) {Boss, Manager} are embedded as value types, not pointer types.
	// 2) This makes it so that only the pointer type *BossManager includes both methods
	// in its method set, thus making it implement interface PromotionMaterial.

	// promote(bm)	// Would fail with: cannot use bm (type BossManager) as type PromotionMaterial in argument to promote:
	// BossManager does not implement PromotionMaterial (AssignWork method has pointer receiver)
	// This would work if {Boss, Manager} were embedded as pointer types.

	promote(&bm) // Works

	// Lets use the struct with the embedded pointer types:
	bm2 := BossManagerUsingPointers{}
	bm2.AssignWork()        // "Boss assigned work"
	bm2.PreparePowerPoint() // "PowerPoint prepared"
	promote(bm2)            // Works
	promote(&bm2)           // Also works, since both BossManagerUsingPointers (value type) and *BossManagerUsingPointers (pointer type)
	// method sets include both methods.
}

  

参考网址:https://unitstep.net/blog/2015/09/16/golang-promoted-methods-method-sets-and-embedded-types/

 

posted @ 2021-11-03 13:41  专职  阅读(256)  评论(0编辑  收藏  举报