英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论