应该使用基于例程/通道的机制替换并发映射吗?

There's a map[PlayerId]Player to check whether player is online and perform state alterations knowing his ID. This must be done from multiple goroutines concurrently.

For now I plan to use streamrail's concurrent map, but what about a regular map and synchronization using channels?

  • Should it always be preferred in Go?
  • Should it be preferred in certain circumstances?
  • Are they basically just two ways to accomplish the same thing?

BTW, I know the slogan:

don't communicate by sharing memory share memory by communicating

but there are locking mechanisms in stdlib and no words in docs about not using them at all.

Start with the simplest approach: a map and RWMutex.

I cannot recommend using concurrency library unless it is widely used and tested (see https://github.com/streamrail/concurrent-map/issues/6 for example).

Note that even if you use github.com/streamrail/concurrent-map you will still need to implement your own synhronisation (use RWMutex) in the following scenario:

if _, ok = m[k]; !ok {
   m[k] = newPlayer()
}

If your game is super popular and played by many players you will find that this approach doesn't scale but I would worry about it only if it becomes a problem.