Golang嵌套struct结合interface使用的指针问题及规范实现方法
Go 接口指针问题与嵌套链式调用的标准实现
问题根源
代码不符合Go的常规设计原则:除非有特殊需求要修改接口本身的赋值,否则永远不要使用指向接口的指针。
Go的接口类型本身就可以存储实现了该接口的任意值(包括值类型、指针类型),*IA这种指向接口的指针完全是多余的,也是导致编译错误、需要手动解引用的核心原因。
绕开写法是否符合规范?
(*(*b).A()).Foo()这种写法完全不符合Go编码规范,可读性极差,属于典型的对Go接口语义理解错误导致的冗余hack写法,没有任何生产环境使用的价值。
嵌套链式调用的标准实现方式
要实现类似someObj.child1.child2.method()的链式调用,只需要把所有涉及接口指针的定义全部改成直接用接口类型即可,不需要额外加指针层。
修正后的可运行代码
package main import "fmt" // IA 定义A的行为接口 type IA interface { Foo() string } type A struct { foo string } func (a *A) Foo() string { return a.foo } // IB 定义B的行为接口 type IB interface { A() IA // 直接返回IA接口类型,不是*IA } type B struct { a IA // 字段直接用IA类型,不是*IA } func (b *B) A() IA { return b.a } func main() { a := &A{"lol"} b := &B{a} // 直接赋值,不需要类型转换 // 直接实现链式调用,和Python/TS中使用体验完全一致 foo := b.A().Foo() fmt.Println(foo) // 输出: lol }
补充说明
如果嵌套的子对象不需要抽象,直接返回具体的结构体指针类型也可以,不需要强行套接口。Go的接口设计原则是「小而美」,只有当你需要对实现做抽象、做替换的时候才定义接口,不要为了写接口而写接口。
内容的提问来源于stack exchange,提问作者Dominux
相关产品推荐
相关产品推荐

