我有一个结构,我想用一些合理的默认值初始化它。

通常,这里要做的事情是使用构造函数,但由于go不是传统意义上的真正面向对象,所以它们不是真正的对象,而且它没有构造函数。

我注意到了init方法,但那是在包级别。是否有其他类似的东西可以在结构层使用?

如果不是,那么在围棋中这类事情的公认最佳实践是什么?


当前回答

我是新来的。我有一个模式从其他语言,有构造函数。并将继续工作。

创建一个init方法。 使init方法成为一个(对象)例程。它只在第一次被调用时运行(每个对象)。

func (d *my_struct) Init (){
    //once
    if !d.is_inited {
        d.is_inited = true
        d.value1 = 7
        d.value2 = 6
    }
}

在该类的每个方法的顶部调用init。

当您需要后期初始化(构造函数太早)时,这种模式也很有用。

优点:它将所有的复杂性隐藏在类中,客户端不需要做任何事情。

缺点:你必须记住在类的每个方法的顶部调用Init。

其他回答

另一种方法是;

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,
    }
}

在官方文件中,Golang并不是面向对象语言。 Golang struct的所有字段都有一个确定的值(不像c/c++),所以构造函数不像cpp那么需要。 如果需要为某些字段分配一些特殊值,请使用工厂函数。 Golang的社区建议新…模式名称。

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

当0值不能作为合理的默认值时,或者当结构初始化需要一些形参时,有一些构造函数的等价函数。

假设你有一个这样的结构:

type Thing struct {
    Name  string
    Num   int
}

然后,如果0值不合适,你通常会构造一个NewThing函数返回一个指针的实例:

func NewThing(someParameter string) *Thing {
    p := new(Thing)
    p.Name = someParameter
    p.Num = 33 // <- a very sensible default value
    return p
}

当你的结构体足够简单时,你可以使用这个压缩结构:

func NewThing(someParameter string) *Thing {
    return &Thing{someParameter, 33}
}

如果你不想返回一个指针,那么一个实践是调用函数makeThing而不是NewThing:

func makeThing(name string) Thing {
    return Thing{name, 33}
}

参考:分配与新的有效Go。

我是新来的。我有一个模式从其他语言,有构造函数。并将继续工作。

创建一个init方法。 使init方法成为一个(对象)例程。它只在第一次被调用时运行(每个对象)。

func (d *my_struct) Init (){
    //once
    if !d.is_inited {
        d.is_inited = true
        d.value1 = 7
        d.value2 = 6
    }
}

在该类的每个方法的顶部调用init。

当您需要后期初始化(构造函数太早)时,这种模式也很有用。

优点:它将所有的复杂性隐藏在类中,客户端不需要做任何事情。

缺点:你必须记住在类的每个方法的顶部调用Init。