Pra*_*eek 112 struct initialization default-value go
以下问题有多种答案/技巧:
我有几个答案,但需要进一步讨论.
vod*_*095 82
一个可能的想法是编写单独的构造函数
//Something is the structure we work with
type Something struct {
Text string
DefaultText string
}
// NewSomething create new instance of Something
func NewSomething(text string) Something {
something := Something{}
something.Text = text
something.DefaultText = "default text"
return something
}
Run Code Online (Sandbox Code Playgroud)
Pra*_*eek 55
强制方法获取结构(构造方式).
一个好的设计是使你的类型不被导出,但提供一个导出的构造函数,如NewMyType(),你可以在其中正确初始化你的结构/类型.还返回接口类型而不是具体类型,接口应包含其他人想要对您的值执行的所有操作.您的具体类型当然必须实现该接口.
这可以通过简单地使类型本身未导出来完成.您可以导出函数NewSomething甚至字段Text和DefaultText,但只是不导出struct类型的东西
为您自己的模块定制它的另一种方法是使用Config结构来设置默认值(链接中的选项5)虽然不是一个好方法.
wol*_*109 24
Victor Zamanian回答选项1的一个问题是,如果未导出类型,则包的用户不能将其声明为函数参数的类型等.解决此问题的方法之一是导出接口而不是结构例如
package candidate
// Exporting interface instead of struct
type Candidate interface {}
// Struct is not exported
type candidate struct {
Name string
Votes uint32 // Defaults to 0
}
// We are forced to call the constructor to get an instance of candidate
func New(name string) Candidate {
return candidate{name, 0} // enforce the default value here
}
Run Code Online (Sandbox Code Playgroud)
这让我们可以使用导出的Candidate接口声明函数参数类型.我可以从这个解决方案中看到的唯一缺点是我们所有的方法都需要在接口定义中声明,但你可以说这无论如何都是好的做法.
来自https://golang.org/doc/ effective_go.html# composite_literals :
有时零值不够好,需要初始化构造函数,如本例中派生自包 os.
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
f := new(File)
f.fd = fd
f.name = name
f.dirinfo = nil
f.nepipe = 0
return f
}
Run Code Online (Sandbox Code Playgroud)
有一种使用标记执行此操作的方法,它允许多个默认值。
假设您具有以下结构,带有2个默认标记default0和default1。
type A struct {
I int `default0:"3" default1:"42"`
S string `default0:"Some String..." default1:"Some Other String..."`
}
Run Code Online (Sandbox Code Playgroud)
现在可以设置默认值。
func main() {
ptr := &A{}
Set(ptr, "default0")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=3 ptr.S=Some String...
Set(ptr, "default1")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=42 ptr.S=Some Other String...
}
Run Code Online (Sandbox Code Playgroud)
如果您对更复杂的示例感兴趣,例如使用切片和地图,那么请看一下creasty / defaultse