以下问题有多种答案/技巧:
我有几个答案,但需要进一步讨论。
答案 0 :(得分:67)
一个可能的想法是编写单独的构造函数
//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
}
答案 1 :(得分:41)
强制方法获取结构(构造方式)。
一个好的设计是让您的类型未导出,但提供导出 像NewMyType()这样的构造函数,你可以正常使用它 初始化您的结构/类型。还返回接口类型而不是a 具体类型,界面应包含其他人想要的一切 与你的价值有关。你的具体类型必须实现这一点 界面当然。
这可以通过简单地使类型本身未导出来完成。您可以导出函数NewSomething甚至字段Text和DefaultText,但只是不要导出结构类型
为您自己的模块自定义它的另一种方法是使用Config struct to set default values(链接中的选项5)不是一个好方法。
答案 2 :(得分:15)
选项1的一个问题在回答中 Victor Zamanian认为,如果类型没有被导出,那么你的包的用户就不能将它声明为函数参数的类型等。一种方法是导出一个接口而不是结构,例如
package candidate
// Exporting interface instead of struct
type Candidate interface {}
// Struct is not exported
type candidate struct {
Name string
Votes unit32 // 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
}
这允许我们使用导出的Candidate接口声明函数参数类型。 我从这个解决方案中可以看到的唯一缺点是我们所有的方法都需要在接口定义中声明,但你可以说这无论如何都是好的做法。
答案 3 :(得分:2)
来自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
}
答案 4 :(得分:2)
有一种方法可以使用标签来做到这一点, 允许多个默认值。
假设您具有以下结构,默认值为2 标签 default0 和 default1 。
type A struct {
I int `default0:"3" default1:"42"`
S string `default0:"Some String..." default1:"Some Other String..."`
}
现在可以设置默认值了。
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...
}
这里是complete program in a playground。
如果您对更复杂的示例感兴趣,请使用 切片和地图,然后看一下creasty/defaultse
答案 5 :(得分:1)
type Config struct {
AWSRegion string `default:"us-west-2"`
}
答案 6 :(得分:1)
一种方法是:
// declare a type
type A struct {
Filed1 string
Field2 map[string]interface{}
}
因此,每当您需要自定义类型的新变量时,只需调用 NewA 函数,您也可以参数化该函数以选择性地将值分配给结构字段
func NewA() *A {
return &A{
Filed1: "",
Field2: make(map[string]interface{}),
}
}