Yes. Rust is for what you'd otherwise have to write in C++. It's overkill for web services. You have to obsess over who owns what. The compiler will catch memory safety errors, but you still have to resolve them. It's quite possible to paint yourself into a corner and have to go back and redesign something. On the other hand, if you really need to coordinate many CPUs in a complicated way, Rust has decent facilities for that.
Goroutines don't have the restrictions of async that you must never block or spend too much time computing. Goroutines are preemptable. The language has memory-safe concurrency (except for maps, which is weird) and has garbage collection. So you can have parallelism without worrying too much about race conditions or leaks.
Go comes with very solid libraries for most server-side web things, because they're libraries Google uses internally. Rust crates have the usual open source problem - they get to 95%-99% debugged, but the unusual cases may not work right. Go has actual paid QA people.
Go has limited aims. It was created so that Google could write their internal server side stuff in something safer than C++ and faster than Python. It has a limited feature set. It's a practical tool.
I write hard stuff (a multi-thread metaverse viewer) in Rust, and easy web stuff (a data logger which updates a database) in Go. Use the right tool for the job.
Most of the time you can also avoid this by just copying data using .clone(). This adds a tiny bit of overhead, which is why it isn't a default - but it'll still be comparatively very efficient.
Similarly, there are facilities for shared mutation (Cell/RefCell) and for multiple owners extending the lifetime of a single piece of data (Rc/Arc). It's not that hard to assess where those might be needed, even in larger programs.
This big time. Rust has comparable ergonomics to high level languages once you stop trying to optimize everything and start throwing around clones liberally. And the nice thing is that if you do need to optimize something later you can trust the compiler that if it compiles, then it’s correct (barring interior mutability/unsafe).
Regarding concurrency and Go, it's truly an awful language from the view of concurrency when coming from Rust. It's a loaded footgun where you have to keep tons implicit details in your mind to get it right.
Minor nitpick but goroutines are absolutely not preemptable, they’re cooperative. The go compiler regularly sticks in yield statements around IO, and certain function calls, but you absolutely can starve the runtime by running a number of goroutines equal to the number of cores doing heavy computation, just like Node.JS’s event loop.
Go's concurrency model is bog-standard shoot your foot off shared memory.
A channel is not magic, it's a multiple-producer multiple-consumer queue, you can unwittingly send a pointer over it (or a pointer-ish, like a hashmap) and boom you've got unchecked concurrent mutations, and in Go that even opens you up to data races (memory unsafety).
And because channels are slow, it's common to go down the stack, and hit further issues of mis-managing your mutexes or waitgroups, to say nothing of spawning a goroutine by closing over a mutable location.
You can do it right, in the same way you can do it right in C, C++, Java, Ruby, or Python. And arguably it's more difficult in Go because it drives you significantly more towards concurrency (and spawning tons of goroutines) without really giving you better tools to manage it (the only one I can think of is select).
Goroutines don't have the restrictions of async that you must never block or spend too much time computing. Goroutines are preemptable. The language has memory-safe concurrency (except for maps, which is weird) and has garbage collection. So you can have parallelism without worrying too much about race conditions or leaks.
Go comes with very solid libraries for most server-side web things, because they're libraries Google uses internally. Rust crates have the usual open source problem - they get to 95%-99% debugged, but the unusual cases may not work right. Go has actual paid QA people.
Go has limited aims. It was created so that Google could write their internal server side stuff in something safer than C++ and faster than Python. It has a limited feature set. It's a practical tool.
I write hard stuff (a multi-thread metaverse viewer) in Rust, and easy web stuff (a data logger which updates a database) in Go. Use the right tool for the job.