美文网首页Go
golang 指针对象 和值对象

golang 指针对象 和值对象

作者: wuhan_goer | 来源:发表于2022-03-28 23:45 被阅读0次

    看下面一段代码

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    type Foo struct {
        sync.RWMutex
        m map[int]int
    }
    
    func (f Foo) PointerMethod(i int) {
        f.RWMutex.Lock()
        f.m[i] = i
        f.RWMutex.Unlock()
    }
    
    func (f Foo) ValueMethod(i int) {
        f.RWMutex.Lock()
        fmt.Println(f.m[i])
        f.RWMutex.Unlock()
    }
    
    func main() {
        f1 := Foo{
            m: make(map[int]int, 0),
        }
        for i := 0; i < 100; i++ {
            go f1.ValueMethod(i)
            go f1.PointerMethod(i)
        }
        time.Sleep(6 * time.Second)
    
    }
    

    执行的结果是:panic 并发读写了 concurrent map writes


    image.png

    出现这种问题是因为采用了值对象导致加锁失败,

    原因:

    如果方法接收者为对象的指针,则会修改原对象,如果方法接收者为对象的值,那么在方法中被操作的是原对象的副本,不会影响原对象

    官方也给了建议:

    如果接收者是一个包含 sync.Mutex 或类似同步字段的结构,则接收者必须是一个指针以避免复制。


    image.png

    解决方法

    改成指针即可


    image.png

    相关文章

      网友评论

        本文标题:golang 指针对象 和值对象

        本文链接:https://www.haomeiwen.com/subject/kwnmjrtx.html