以下问题有多种答案/技巧:
如何将默认值设置为golang结构? 如何初始化结构在golang
我有几个答案,但还需要进一步讨论。
以下问题有多种答案/技巧:
如何将默认值设置为golang结构? 如何初始化结构在golang
我有几个答案,但还需要进一步讨论。
当前回答
从https://golang.org/doc/effective_go.html # composite_literals:
有时0值还不够好,需要初始化构造函数,就像这个从包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
}
其他回答
有一种使用标签的方法 允许多个默认值。
假设您有以下结构,默认有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...
}
这是一个操场上的完整程序。
如果你对一个更复杂的例子感兴趣,可以说with 切片和映射,然后,看看creasty/defaultse
结构体
使这个程序更好的一个简单方法是使用结构体。struct是一种包含命名字段的类型。例如,我们可以这样表示一个圆:
type Circle struct {
x float64
y float64
r float64
}
type关键字引入了一个新类型。后面跟着类型的名称(Circle)、关键字struct(表示我们正在定义结构类型)和花括号内的字段列表。每个字段都有一个名称和类型。像函数一样,我们可以折叠具有相同类型的字段:
type Circle struct {
x, y, r float64
}
初始化
我们可以用多种方式创建Circle类型的实例:
var c圆 与其他数据类型一样,这将创建一个默认设置为0的本地Circle变量。对于结构体,0表示每个字段都被设置为相应的0值(0表示整型,0.0表示浮点数,""表示字符串,nil表示指针,…)
c := new(Circle)
这将为所有字段分配内存,将每个字段设置为0值并返回一个指针。(*圆圈)更多时候,我们想给每个字段一个值。我们可以用两种方法做到这一点。是这样的:
c := Circle{x: 0, y: 0, r: 5}
或者,如果我们知道字段的定义顺序,我们可以省略字段名:
c := Circle{0, 0, 5}
从https://golang.org/doc/effective_go.html # composite_literals:
有时0值还不够好,需要初始化构造函数,就像这个从包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
}
选项1的一个问题是 Victor Zamanian认为,如果没有导出类型,那么包的用户就不能将其声明为函数参数的类型等。解决这个问题的一种方法是导出一个接口,而不是输出结构。
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
}
这允许我们使用导出的Candidate接口声明函数参数类型。 我从这个解决方案中看到的唯一缺点是,我们所有的方法都需要在接口定义中声明,但你可能会说这是一种很好的实践。
一种可能的想法是编写单独的构造函数
//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
}