Go语言内嵌结构体(一)

85 阅读1分钟

简介

在Go语言中,可以通过「内嵌结构体」的方式「继承和扩展」已有的结构体,并且可以实现「代码的复用」
内嵌后当前结构体会「自动获得」嵌入的结构体的所有字段和方法,就好像它们是直接定义在当前结构体中一样
注意,如果嵌入的结构体和当前结构体有重名的字段或方法,那么在访问时需要使用完整的字段或方法名称。

代码测试

type Error interface {
   error
   GetName() string
   SetName(name string)
}

type baseErr struct {
   Name  string
   cause error

   // testDuplicateAttr 测试重名属性
   testDuplicateAttr string
}

func (b *baseErr) Error() string {
   return fmt.Sprintf("baseErr detail: name:%s, testDuplicateAttr:%s", b.Name, b.testDuplicateAttr)
}

func (b *baseErr) GetName() string {
   return b.Name
}
func (b *baseErr) SetName(name string) {
   b.Name = name
}

type ErrorWithCode interface {
   Error
   GetCode() int64
   SetCode(code int64)
}

type errorWithCode struct {
   // 内嵌
   *baseErr
   Code int64
   // testDuplicateAttr 测试重名属性
   testDuplicateAttr string
}

func (b *errorWithCode) Error() string {
   return fmt.Sprintf("errorWithCode detail: name:%s, code:%d, testDuplicateAttr:%s", b.Name, b.Code, b.testDuplicateAttr)
}
func (b *errorWithCode) GetCode() int64 {
   return b.Code
}
func (b *errorWithCode) SetCode(code int64) {
   b.Code = code
}

func main() {
   err0 := &errorWithCode{
      // 内嵌
      baseErr: &baseErr{
         Name:              "base err",
         testDuplicateAttr: "base err attr",
         cause:             fmt.Errorf("test cause"),
      },
      Code:              1,
      testDuplicateAttr: "errorWithCode attr",
   }

   var errI Error
   errI = err0
   // 测试重名方法Error
   fmt.Println(errI.Error())
   fmt.Println(errI.GetName())
   fmt.Println("---errI end-----")

   // 获得内嵌结构体的方法
   fmt.Println(err0.GetName())
   // 获得内嵌结构体的属性
   fmt.Println(err0.cause)
   fmt.Println("------")

   // 重名方法
   fmt.Println(err0.Error())
   fmt.Println(err0.baseErr.Error())
   // 重名属性
   fmt.Println(err0.testDuplicateAttr)
   fmt.Println(err0.baseErr.testDuplicateAttr)
}