1. 程式人生 > 其它 >golang中值型別的嵌入式欄位和指標型別的嵌入式欄位

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/