我有一个结构,我想用一些合理的默认值初始化它。
通常,这里要做的事情是使用构造函数,但由于go不是传统意义上的真正面向对象,所以它们不是真正的对象,而且它没有构造函数。
我注意到了init方法,但那是在包级别。是否有其他类似的东西可以在结构层使用?
如果不是,那么在围棋中这类事情的公认最佳实践是什么?
我有一个结构,我想用一些合理的默认值初始化它。
通常,这里要做的事情是使用构造函数,但由于go不是传统意义上的真正面向对象,所以它们不是真正的对象,而且它没有构造函数。
我注意到了init方法,但那是在包级别。是否有其他类似的东西可以在结构层使用?
如果不是,那么在围棋中这类事情的公认最佳实践是什么?
当前回答
在Go中,构造函数可以使用返回已修改结构的指针的函数来实现。
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
对于弱依赖和更好的抽象,构造函数不返回指向结构的指针,而是返回该结构实现的接口。
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}
其他回答
在官方文件中,Golang并不是面向对象语言。 Golang struct的所有字段都有一个确定的值(不像c/c++),所以构造函数不像cpp那么需要。 如果需要为某些字段分配一些特殊值,请使用工厂函数。 Golang的社区建议新…模式名称。
Go有对象。对象可以有构造函数(尽管不是自动构造函数)。最后,Go是一种面向对象语言(数据类型有附加的方法,但不可否认,关于什么是面向对象有无数的定义)。
然而,公认的最佳实践是为类型编写零个或多个构造函数。
因为@dystroy在我完成这个答案之前发布了他的答案,让我添加一个他的示例构造函数的替代版本,我可能会写成:
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33} // <- 33: a very sensible default value
}
我想向您展示这个版本的原因是,通常可以使用“内联”字面量来代替“构造函数”调用。
a := NewThing("foo")
b := &Thing{"foo", 33}
现在*a == *b。
另一种方法是;
package person
type Person struct {
Name string
Old int
}
func New(name string, old int) *Person {
// set only specific field value with field key
return &Person{
Name: name,
}
}
Go中没有默认的构造函数,但是你可以为任何类型声明方法。您可以习惯声明一个名为“Init”的方法。不确定这是否与最佳实践有关,但它有助于保持名称简短而不失去清晰度。
package main
import "fmt"
type Thing struct {
Name string
Num int
}
func (t *Thing) Init(name string, num int) {
t.Name = name
t.Num = num
}
func main() {
t := new(Thing)
t.Init("Hello", 5)
fmt.Printf("%s: %d\n", t.Name, t.Num)
}
结果是:
Hello: 5
在Go中,构造函数可以使用返回已修改结构的指针的函数来实现。
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
对于弱依赖和更好的抽象,构造函数不返回指向结构的指针,而是返回该结构实现的接口。
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}