为了账号安全,请及时绑定邮箱和手机立即绑定

函数按值返回锁

函数按值返回锁

Go
偶然的你 2022-01-10 16:36:45
我有以下结构    type Groups struct {        sync.Mutex        Names []string    }和以下功能    func NewGroups(names ...string) (Groups, error) {        // ...        return groups, nil    }当我检查语义错误时go vet,我收到以下警告:NewGroups 按值返回 Lock:组像go vet喊叫一样,不好。这段代码会带来什么问题?我怎样才能解决这个问题?
查看完整描述

2 回答

?
森栏

TA贡献1810条经验 获得超5个赞

您需要将 sync.Mutex 作为指针嵌入:


type Groups struct {

    *sync.Mutex

    Names []strng

}

解决您对问题的评论:在文章http://blog.golang.org/go-maps-in-action通知中,Gerrand 没有从函数返回结构,而是立即使用它,这就是为什么他不是t 使用指针。在您的情况下,您将返回它,因此您需要一个指针,以免复制 Mutex。


更新:正如@JimB 指出的那样,嵌入指向 的指针可能并不谨慎sync.Mutex,最好返回指向外部结构的指针并继续将 嵌入sync.Mutex作为值。考虑一下您在特定情况下要完成的工作。


查看完整回答
反对 回复 2022-01-10
?
交互式爱情

TA贡献1712条经验 获得超3个赞

*Groups而是返回一个指针。


嵌入互斥指针也可以,但有两个缺点,需要您格外小心:


结构的零值将有一个 nil 互斥体,因此您必须每次显式初始化它

func main() {

    a, _ := NewGroups()

    a.Lock() // panic: nil pointer dereference

}


func NewGroups(names ...string) (Groups, error) {

    return Groups{/* whoops, mutex zero val is nil */ Names: names}, nil

}

分配一个结构值,或将其作为函数 arg 传递,会创建一个副本,因此您还可以复制互斥指针,然后锁定所有副本。(在某些特定情况下,这可能是一个合法的用例,但大多数时候它可能不是您想要的。)

func main() {   

    a, _ := NewGroups()

    a.Lock()

    lockShared(a)

    fmt.Println("done")

}


func NewGroups(names ...string) (Groups, error) {

    return Groups{Mutex: &sync.Mutex{}, Names: names}, nil

}


func lockShared(g Groups) {

    g.Lock() // whoops, deadlock! the mutex pointer is the same

}

保留原始结构并返回指针。您不必显式地初始化嵌入式互斥锁,而且很直观,互斥锁不与您的结构副本共享。


func NewGroups(names ...string) (*Groups, error) {

    // ...

    return &Groups{}, nil

}

游乐场(有失败的例子):https : //play.golang.org/p/CcdZYcrN4lm


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信