4 ms·
his SafeSet implementation exposes functionality as exported fields instead of exported methods. That should be a red flag to anybody with any real-world Go ex
by zemo 14y ago
his SafeSet implementation exposes functionality as exported fields instead of exported methods. That should be a red flag to anybody with any real-world Go experience. Exposing functionality through channel fields obviates the possibility of generalizing the functionality as an interface. It also creates subtle traps, where the caller must now know whether they're expected to set these channels to be buffered or unbuffered.
If you're dead-set on implementing this with channels, those channels should be unexported and hidden:
http://play.golang.org/p/zRSco7MpMl http://play.golang.org/p/zRSco7MpMl
In reality, it's far more sane to just say `type SafeSet struct { d map[string]bool; mu sync.Mutex }`, again exposing all the functionality through methods, and just locking and unlocking the mutex as necessary. If using a mutex makes the implementation more clear and is semantically equivalent, then use a mutex. That's not typically the case, because typically the case involves more than just locking and unlocking. In this particular example, all you need to do is lock some resource, so it's ok to just use a lock.
And the claim that there's no data privacy isn't correct, it just assumes a data privacy model that Go doesn't have, namesly the "public" and "private" notions. Go instead opts for the notion of "exported" and "unexported" fields and methods; i.e., fields and methods that may be used only by code within the same package. It's a different mechanism for hiding data, but it does exist.
Anywho, if you want to see a completely absurd, lock-free (not strictly nonblocking), threadsafe queue in 51 lines of Go using higher order channels, just for kicks, see here: https://gist.github.com/3668150 https://gist.github.com/3668150