首页 > 解决方案 > 在方法或构造函数级别进行零处理?

问题描述

我应该在构造函数中检查 nil 值,然后设置一个未导出的结构字段,还是通过在方法级别检查 nil 来使默认结构值有用?

type Foo struct{}

func (f *Foo) Baz() {}

var DefaultFoo = new(Foo)

type Bar struct {
    Foo *Foo
}

func (b *Bar) Baz() {
    if b.Foo == nil {
        DefaultFoo.Baz()
    } else {
        b.Foo.Baz()
    }
}

或者

type Foo struct{}

func (f *Foo) Baz() {}

var DefaultFoo = new(Foo)

type Bar struct {
    foo *Foo
}

func NewBar(foo *Foo) *Bar {
    if foo == nil {
        foo = DefaultFoo
    }
    return &Bar{foo}
}

func (b *Bar) Baz() {
    b.foo.Baz()
}

标签: gostructnullconventions

解决方案


我认为对此没有“正确”的答案。

话虽如此,在 Go 基础库中通常看到的方法是让对象在没有任何构造函数的情况下创建,在其字段中使用nilorzero值,然后使方法具有使用逻辑或返回有用的默认值。

http.Client实现为例:

https://github.com/golang/go/blob/master/src/net/http/client.go

它基本上让您只需执行以下操作即可创建一个新客户端:

client := &http.Client{}

如果要覆盖默认值,则可以填充对象的字段,否则它将检查nil不同的方法以提供默认行为,例如:

https://github.com/golang/go/blob/master/src/net/http/client.go#L195

func (c *Client) transport() RoundTripper {
    if c.Transport != nil {
        return c.Transport
    }
    return DefaultTransport
}

推荐阅读