Is there standard idiomatic Go for "constructors"?

huangapple go评论91阅读模式
英文:

Is there standard idiomatic Go for "constructors"?

问题

给定以下代码:

type AStruct struct {
    m_Map map[int]bool
}

在这种情况下,只有在初始化AStruct.m_Map之后,才能使用AStruct的实例:

m_Map=make(map[int]bool,100)

我已经习惯了在这种情况下为我的结构体编写一个Init()函数:

func (s *AStruct) Init() {
    s.m_Map=make(map[int]bool,100)
}

我不是特别喜欢这种设计,因为它要求(s *AStruct) Init()是公开的,并且要求客户在使用AStuct实例之前显式调用它 - 在此期间,一个无法使用的AStuct实例存在,等待生成panic

我可以将init()设置为私有,并在struct中声明一个initialized bool标志,在init()中初始化完成后将其设置为true,并在每个方法中进行检查:

func (s *AStruct) DoStuff {

    if !s.initialized {
         s.init()
    }
    
    s.m_Map[1]=false
    s.m_Map[2]=true
}

但这很笨拙,而且增加了多余的代码。

在Go语言中是否有一种标准的处理方式?一种可以保证m_Map在不依赖客户端调用Init()的情况下被初始化的方式?

英文:

Given the following:

type AStruct struct {
    m_Map map[int]bool
}

In this case, an instance ofAStructcannot be used untilAStruct.m_Mapis initialized:

m_Map=make(map[int]bool,100)

I have taken to writing an Init()function for my structs in such cases:

func (s *AStruct) Init() {
    s.m_Map=make(map[int]bool,100)
}

I don't particularly care for this design, because it requires(s *AStruct) Init() to be public and mandates that clients call it explicitly before using an instance of AStuct - in the interim an unusable instance ofAStuctis out there, waiting to generate apanic.

I could make init() private and declare an initialized boolflag in thestruct set ittrueininit()after everything is initialized and check in each method:

func (s *AStruct) DoStuff {

    if !s.initialized {
         s.init()
    }
    
    s.m_Map[1]=false
    s.m_Map[2]=true
}

But this is awkward and adds superfluous code.

Is there is standard way of handling this in Go? One that guarantees m_Map will be initialized without relying on clients to call Init()?

答案1

得分: 10

类型Foo的标准是编写一个名为NewFoo()的构造函数,它不是类型上的方法,而是返回一个类型为Foo(或*Foo)的值。只要所有的Foo实例都是通过调用NewFoo()生成的(而不是通过字面值或调用new()内置函数生成的),那么就是安全的。

英文:

The standard for a type Foo is to write a constructor NewFoo() which is not a method on the type, but returns a value of type Foo (or *Foo). Then as long as all instances of Foo are generated through a call to NewFoo() (and not through a literal or a call to the new() builtin) then you're safe.

huangapple
  • 本文由 发表于 2014年3月30日 04:32:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/22736535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定