简介
在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)
}