Concurrent access to maps with 'range' in Go
<p>The "<a href="https://blog.golang.org/go-maps-in-action" rel="noreferrer">Go maps in action</a>" entry in the Go blog states: </p>

<blockquote>
  <p>Maps are not safe for concurrent use: it's not defined what happens when you read and write to them simultaneously. If you need to read from and write to a map from concurrently executing goroutines, the accesses must be mediated by some kind of synchronization mechanism. One common way to protect maps is with sync.RWMutex.</p>
</blockquote>

<p>However, one common way to access maps is to iterate over them with the <code>range</code> keyword. It is not clear if for the purposes of concurrent access, execution inside a <code>range</code> loop is a "read", or just the "turnover" phase of that loop.  For example, the following code may or may not run afoul of the "no concurrent r/w on maps" rule, depending on the specific semantics / implementation of the <code>range</code> operation:</p>

<pre><code> var testMap map[int]int
 testMapLock := make(chan bool, 1)
 testMapLock &lt;- true
 testMapSequence := 0
</code></pre>

<p>...</p>

<pre><code> func WriteTestMap(k, v int) {
    &lt;-testMapLock
    testMap[k] = v
    testMapSequence++
    testMapLock&lt;-true
 }

 func IterateMapKeys(iteratorChannel chan int) error {
    &lt;-testMapLock
    defer func() { 
       testMapLock &lt;- true
    }
    mySeq := testMapSequence
    for k, _ := range testMap {
       testMapLock &lt;- true
       iteratorChannel &lt;- k
       &lt;-testMapLock
       if mySeq != testMapSequence {
           close(iteratorChannel)
           return errors.New("concurrent modification")
       }
    }
    return nil
 }
</code></pre>

<p>The idea here is that the <code>range</code> "iterator" is open when the second function is waiting for a consumer to take the next value, and the writer is not blocked at that time.   However, it is never the case that two reads in a single iterator are on either side of a write - this is a "fail fast" iterator, the borrow a Java term.</p>

<p>Is there anything anywhere in the language specification or other documents that indicates if this is a legitimate thing to do, however?   I could see it going either way, and the above quoted document is not clear on exactly what consititutes a "read". The documentation seems totally quiet on the concurrency aspects of the <code>for</code>/<code>range</code> statement. </p>

<p>(Please note this question is about the currency of <code>for/range</code>, but not a duplicate of: <a href="https://stackoverflow.com/questions/34080734/golang-concurrent-map-access-with-range">Golang concurrent map access with range</a> - the use case is completely different and I am asking about the precise locking requirement wrt the 'range' keyword here!)</p>