title: Can you get a data race when deferring a mutex unlock in go?
body: <p>Is this Get method buggy and prone to a theoretical data race?</p>
  
  <pre><code>type item struct {
      val   int
      mutex sync.RWMutex
  }
  
  func (i *item) Set(val int) {
      i.mutex.Lock()
      defer i.mutex.Unlock()
      i.val = val
  }
  
  func (i *item) Get() int {
      i.mutex.RLock()
      defer i.mutex.RUnlock()
      return i.val
  }
  </code></pre>
  
  <p>I ask because I saw a rare data race when running my tests with <code>-race</code> with the former code, but can't find any way of duplicating the effect.</p>
  
  <p>Is it possible for i.val to be set to a different value between when the defer carries out the RUnlock, and when we read and return the value from the struct?</p>
  
  <p>Must Get() be something like this instead?:</p>
  
  <pre><code>func (i *item) Get() int {
      i.mutex.RLock()
      defer i.mutex.RUnlock()
      val := i.val
      return val
  }
  </code></pre>