如何初始化Go结构体中的成员

发布于 2024-10-08 14:55:27 字数 582 浏览 3 评论 0原文

我是 Golang 新手,所以其中的分配让我发疯:

import "sync"

type SyncMap struct {
        lock *sync.RWMutex
        hm map[string]string
}
func (m *SyncMap) Put (k, v string) {
        m.lock.Lock()
        defer m.lock.Unlock()

        m.hm[k] = v, true
}

后来,我只是调用:

sm := new(SyncMap)
sm.Put("Test, "Test")

此时我遇到了 nil 指针恐慌。

我已经通过使用另一个函数并在 new() 之后调用它来解决这个问题:

func (m *SyncMap) Init() {
        m.hm = make(map[string]string)
        m.lock = new(sync.RWMutex)
}

但我想知道是否可以摆脱这个样板初始化?

I am new to Golang so allocation in it makes me insane:

import "sync"

type SyncMap struct {
        lock *sync.RWMutex
        hm map[string]string
}
func (m *SyncMap) Put (k, v string) {
        m.lock.Lock()
        defer m.lock.Unlock()

        m.hm[k] = v, true
}

and later, I just call:

sm := new(SyncMap)
sm.Put("Test, "Test")

At this moment I get a nil pointer panic.

I've worked around it by using another one function, and calling it right after new():

func (m *SyncMap) Init() {
        m.hm = make(map[string]string)
        m.lock = new(sync.RWMutex)
}

But I wonder, if it's possible to get rid of this boilerplate initializing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

永不分离 2024-10-15 14:55:27

你只需要一个构造函数。一个常见的使用模式是,

func NewSyncMap() *SyncMap {
    return &SyncMap{hm: make(map[string]string)}
}

如果结构中有更多字段,启动一个 goroutine 作为后端,或者注册一个终结器,一切都可以在此构造函数中完成。

func NewSyncMap() *SyncMap {
    sm := SyncMap{
        hm: make(map[string]string),
        foo: "Bar",
    }

    runtime.SetFinalizer(sm, (*SyncMap).stop)

    go sm.backend()

    return &sm
}

You just need a constructor. A common used pattern is

func NewSyncMap() *SyncMap {
    return &SyncMap{hm: make(map[string]string)}
}

In case of more fields inside your struct, starting a goroutine as backend, or registering a finalizer everything could be done in this constructor.

func NewSyncMap() *SyncMap {
    sm := SyncMap{
        hm: make(map[string]string),
        foo: "Bar",
    }

    runtime.SetFinalizer(sm, (*SyncMap).stop)

    go sm.backend()

    return &sm
}
暖伴 2024-10-15 14:55:27

由于互斥体未初始化,“Mue”的解决方案不起作用。以下修改有效:

package main

import "sync"

type SyncMap struct {
        lock *sync.RWMutex
        hm map[string]string
}

func NewSyncMap() *SyncMap {
        return &SyncMap{lock: new(sync.RWMutex), hm: make(map[string]string)}
}

func (m *SyncMap) Put (k, v string) {
        m.lock.Lock()
        defer m.lock.Unlock()
        m.hm[k] = v
}

func main() {
    sm := NewSyncMap()
    sm.Put("Test", "Test")
}

http://play.golang.org/p/n-jQKWtEy5

The solution of 'Mue' doesn't work since the mutex is not initialized. The following modification works:

package main

import "sync"

type SyncMap struct {
        lock *sync.RWMutex
        hm map[string]string
}

func NewSyncMap() *SyncMap {
        return &SyncMap{lock: new(sync.RWMutex), hm: make(map[string]string)}
}

func (m *SyncMap) Put (k, v string) {
        m.lock.Lock()
        defer m.lock.Unlock()
        m.hm[k] = v
}

func main() {
    sm := NewSyncMap()
    sm.Put("Test", "Test")
}

http://play.golang.org/p/n-jQKWtEy5

画离情绘悲伤 2024-10-15 14:55:27

执事抓得好。 Mue 可能正在考虑更常见的模式,将锁作为值而不是指针包含在内。由于互斥体的零值是一种随时可用的未锁定互斥体,因此它不需要初始化,并且包含 1 作为值是很常见的。为了进一步简化,您可以通过省略字段名称来嵌入它。然后,您的结构体获取互斥体的方法集。请参阅此工作示例,http://play.golang.org/p/faO9six-Qx。我还去掉了 defer 的使用。在某种程度上,这是一个偏好和编码风格的问题,但由于它确实有很小的开销,所以我倾向于不在小函数中使用它,特别是在没有条件代码的情况下。

Good catch by deamon. Mue was possibly thinking of the more common pattern of including the lock as a value rather than a pointer. Since the zero value of a Mutex is a ready-to-use unlocked Mutex, it requires no initialization and including one as a value is common. As a further simplification, you can embed it by omitting the field name. Your struct then acquires the method set of the Mutex. See this working example, http://play.golang.org/p/faO9six-Qx. Also I took out the use of defer. To some extent it's a matter of preference and coding style, but since it does have a small overhead, I tend not to use it in small functions, especially if there is no conditional code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文