Uber Go 语言编程规范:结构体中的嵌入

嵌入类型(比如互斥锁)应该位于结构体的字段列表的顶部(第一个),并且嵌入字段和常规字段之间必须有一个空行予以区分。

Bad

type Client struct {
  version int
  http.Client
}

Good

type Client struct {
  //嵌入类型位于结构体字段列表的顶部
  http.Client

  //空行分割
  version int
}

嵌入应该提供切实的好处,比如以语义合适的方式添加或扩充功能。这样做应该不会对用户产生不利影响(另外请查阅 Avoid Embedding Types in Public Structs

如果有以下几点,就不应该使用嵌入:

  • 纯粹是为了美观或方便。
  • 使外部类型更难于构造或使用。
  • 影响外部类型的零值。如果外部类型有一个有用的零值,那么在嵌入内部类型之后,它仍然应该有一个有用的零值
  • 作为嵌入内部类型的副作用,从外部类型公开不相关的函数或字段。
  • 暴露了未导出类型。
  • 影响外部类型的复制语义。
  • 改变了外部类型的API或类型语义
  • 嵌入了一个非规范形式的内部类型。
  • 暴露了外部类型的实现细节。
  • 允许用户观察或控制内部组件类型。
  • 通过包装来改变内部函数的一般行为,这种包装方式一定会让用户感到疑惑。

简单地说,要有意识地目的明确地去嵌入。一个好的测试技巧是,“是否所有的这些(内嵌类型)导出的内部方法/字段,都能够被直接添加到外部类型中”;如果答案是"some"或"no",那么不要嵌入内部类型,而是使用一个字段来代替。

Bad

//可以使用 A.Lock() 和 A.Unlock(),没有提供任何功能上的好处,并且还能够允许
//用户去控制A的内部的详细细节
type A struct {
    // Bad: A.Lock() and A.Unlock() are
    //      now available, provide no
    //      functional benefit, and allow
    //      users to control details about
    //      the internals of A.
    sync.Mutex
}

Good

//为了特定的目的,在外层提供了Write()方法,并将具体实现委托给内部类型WriteCloser的Write()方法
type countingWriteCloser struct {
    // Good: Write() is provided at this
    //       outer layer for a specific
    //       purpose, and delegates work
    //       to the inner type's Write().
    io.WriteCloser

    count int
}

func (w *countingWriteCloser) Write(bs []byte) (int, error) {
    w.count += len(bs)
    return w.WriteCloser.Write(bs)
}

Bad

type Book struct {
    // Bad: pointer changes zero value usefulness
    io.ReadWriter

    // other fields
}

// later

//外部类型应该还是有一个有用的零值
var b Book
b.Read(...)  // panic: nil pointer
b.String()   // panic: nil pointer
b.Write(...) // panic: nil pointer

Good

type Book struct {
    // Good: has useful zero value
    bytes.Buffer

    // other fields
}

// later

var b Book
b.Read(...)  // ok
b.String()   // ok
b.Write(...) // ok

Bad

type Client struct {
    //所有的这些导出的内嵌类型的内部方法/字段,都能够被直接添加到外部类型中了
    sync.Mutex
    sync.WaitGroup
    bytes.Buffer
    url.URL
}

Good

type Client struct {
    mtx sync.Mutex
    wg  sync.WaitGroup
    buf bytes.Buffer
    url url.URL
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamCatcher

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值