Go 中的构建器函数(Constructor)
Go没有像构造函数那样的OOP,但建议使用类似构造函数的函数来初始化类型。在这篇文章中,我将列出一些构造函数的用例。这些只是构造函数的一些惯用用法,而不是任何受语言限制的约束。所有示例均取自Go内置库。
使用非零默认值初始化类型
在所有这些情况下,声明变量或调用new
,或使用不带任何显式值的复合文字,或调用make
-在所有这些情况下,我们得到的值为零。但是有时我们希望使用一些合理的非零值来初始化变量。这是构造函数最常见的用例。我们几乎可以在所有内置软件包中找到这种用法。例如在encoding / json
包中:
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
我们还可以使用构造函数来进行一些非平凡的初始化。例如,在ring列表中,创建n个元素的环列表的唯一方法是通过构造函数。如果没有构造函数,我们最终将仅拥有一个元素的环形列表。
具有不同初始值的多个构造函数
通常,我们可能需要根据不同的初始内容来构造类型。我们可以使用一个带有多个可选参数的构造函数,也可以使用多个带有不同参数的构造函数。例如,从[bytes
程序包中查看以下定义:
func NewBuffer(buf []byte) *Buffer //使用[] byte作为初始内容初始化缓冲区
func NewBufferString(s string) *Buffer //使用字符串作为初始内容初始化缓冲区
来自bufio
软件包的另一个示例:
// NewReaderSize返回一个新的Reader,其缓冲区至少具有指定的大小。
func NewReaderSize(rd io.Reader, size int) *Reader
// NewReader返回一个新的Reader,其缓冲区具有默认大小。
func NewReader(rd io.Reader) *Reader
防止用户直接修改私有类型,例如封装形式
我们可以将类型声明为私有,还可以从构造函数中返回接口类型。这样,用户将无法直接操作我们的类型。处理类型的唯一方法是使用接口方法。例如,以下是软件包md5
的片段。使用该类型的唯一方法是使用构造函数,并对任何操作使用hash.Hash32
接口方法。
// Private type and private fields
type digest struct {
s [4]uint32
// some other private fields
}
// Return type for New() is an interface type
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
在这里使用接口类型作为返回类型至关重要,否则,即使类型本身是私有的,我们也可以直接更改结构的任何公共字段。
这是errors
包中的另一个示例:
// New返回一个错误,该错误的格式为给定的文本。
func New(text string) error {
return &errorString{text}
}
// errorString是错误的简单实现。
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
将预先声明的类型error
定义为接口:
type error interface {
Error() string
}
最后,我看到人们使用构造函数实现Factory方法模式。我不在此列出,因为我不是这种模式的忠实拥护者。太多的抽象冻结了我的大脑:(
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: