▲ | advisedwang 5 days ago | ||||||||||||||||||||||||||||
Wow that's a really big gotcha in go! To be fair though, go has a big emphasis on using its communication primitives instead of directly sharing memory between goroutines [1]. | |||||||||||||||||||||||||||||
▲ | TheDong 5 days ago | parent | next [-] | ||||||||||||||||||||||||||||
Even if you use channels to send things between goroutines, go makes it very hard to do so safely because it doesn't have the idea of sendable types, ownership, read-only references, and so on. For example, is the following program safe, or does it race?
The answer is of course that it's a data race. Why?Because `buf.Bytes()` returns the underlying memory, and then `Reset` lets you re-use the same backing memory, and so "processData" and "main" are both writing to the same data at the same time. In rust, this would not compile because it is two mutable references to the same data, you'd either have to send ownership across the channel, or send a copy. In go, it's confusing. If you use `bytes.Buffer.ReadBytes("\n")` you get a copy back, so you can send it. Same for `bytes.Buffer.String()`. But if you use `bytes.Buffer.Bytes()` you get something you can't pass across a channel safely, unless you also never use that bytes.Buffer again. Channels in rust solve this problem because rust understands "sending" and ownership. Go does not have those things, and so they just give you a new tool to shoot yourself in the foot that is slower than mutexes, and based on my experience with new gophers, also more difficult to use correctly. | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
▲ | zozbot234 5 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||
Real-world golang programs share memory all the time, because the "share by communicating" pattern leads to pervasive logical problems, i.e. "safe" race conditions and "safe" deadlocks. | |||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||
▲ | Mawr 4 days ago | parent | prev [-] | ||||||||||||||||||||||||||||
Wow who knew concurrency is hard! This isn't anything special, if you want to start dealing with concurrency you're going to have to know about race conditions and such. There is no language that can ever address that because your program will always be interacting with the outside world. |