Go has an well-designed, integrated lightweight thread scheduler. The only popular languages with equivalent lightweight threading systems are Haskell, which takes orders of magnitude longer to master than Go, and Erlang/Elixir, which lack static typing. There's also Clojure with Pulsar, but Clojure lacks statically typed libraries, and the Java equivalent of Pulsar, which is ugly to use compared to goroutines as it's not a built-in language feature and Java syntax can't easily be extended like Clojure's.
Rust has libgreen, but it is extremely underdeveloped compared to the schedulers/runtimes mentioned above. For developers interested in static typing, lightweight CSP-style threads and ease of learning, Go hence currently represents a much better choice than Rust.
From what I've seen over the last 10 or so years programming in both static (C++,Java,C#) and dynamic languages (Erlang, Python) things like "I got a string but expected an int" are pretty low on the list of what fails or brings a project down. Especially when it comes to distributed systems, thing like netsplits, logic and timing errors, mis-configuration, capacity overload are much more serious things.
Now you can argue static typing means really fast speed. And it is generally true. But lately with v8, PyPy and other such things that lines gets a bit blurry.
In my experience - also using both static (C++, Java, Go, Sawzall) and dynamic (PHP, Python, Javascript) languages - I don't get type errors either. However, what actually brings dynamic languages down in larger systems is the time spent tracing through code to figure out what the actual type of the variable is, and hence what you can do with it. When a script is small this is negligible, but when you've got large teams and hundreds of source files, you can spend 10x the time doing this than actually coding.
I view static typing as essential to larger projects, but for documentation reasons, not performance. The performance and error-checking is a nice boon, but you can recover the former with smart VMs and the latter with unit tests. The documentation can only be recovered by writing your types out in comments, where they won't be checked by the compiler and invariably become out-of-date.
You are right, it would help with documentation, good point.
In general I use integration and unit tests for checking breakage. And of course documentation is in comments but that is not forced. The first set of unit or integration tests also function as "example code". Even when reading documentation I usually gravitate to "examples" section quickly anyway.
I just had smaller components that are rather independent if I can. It depends on the project of course. I guess I've been doing micro-services before they were cool.
It's not initially that it's an issue. Refactoring is where static typing shines.
When you change an anonymous (or otherwise ungreppable) function that's passed around all over from taking a string to an int, it's great to have the compiler tell you that you really did find and fix all calls to the function.
Spot on. Right now if you want to build any kind of highly concurrent server or daemon Go is just so immensely practical and productive.
Channels are very easy to work with and both the scheduler and the large standard library are rock solid.
I used to us Haskell for building these kind of services, and it's awesome as well, but has pretty much the largest learning curve of any somewhat mainstream programming language.
Go, on the other hand, can be picked up in a couple of days by anyone familiar with C.
Rust has the potential to be awesome for these kinda services, but the learning curve will always be much higher than Go and right now the scheduling/standard library is still not comparable.
I think that's an important thing though. Rust doesn't need to have concurrency built into the language like Go. With Go you are using their version of concurrency. With Rust, you can use the standard libraries or find another library that suits your purpose.
So although Go does indeed have a well designed thread scheduler - I may discover after months of development on a project it isn't the thread system I need after all and now I'm stuck with a bunch of code I can't use.
Rust in general is far more underdeveloped than everything you mentioned and yes, right now, Go is probably a better choice - maybe.
Rust has libgreen, but it is extremely underdeveloped compared to the schedulers/runtimes mentioned above. For developers interested in static typing, lightweight CSP-style threads and ease of learning, Go hence currently represents a much better choice than Rust.