The major differences in my head are:
- Garbage Collection
- Interfaces
There are some other more minor things like defer and the built-in generic types but many C programmers already had macros to implement similar things.
So sure, Go doesn't solve all of the problem spaces that C does. But if you are in a problem space where you don't need see (or another low-level systems language) Go may be a middle ground to move C programmers to.
So currently the issue is you can't write baremetal stuff in Go, for example the linux kernel or Arduinos. You can't get rid of GC if you have realtime requirements.
GO is 'close enough' to C in many areas like writing server-side code and CLI tools - it's GC pauses are short, even though C could produce an executables in a few KB, rather than an MB, that has no practical relevance in those areas.
If I needed a C alternative, rust gives me all (most of) the power of C, plus safety, without all the drawbacks of a heavy runtime.
If I am okay with paying the garbage collection tax, etc, then I would use scala or kotlin. If I'm using a higher level language, then I expect higher level features like exceptions, generics, reflection, etc.
I'm sure go is a great language with it's own usecases, but it's not a C replacement.
Most of the C lovers that I have spoken with find that Rust is far too complicated with templates and lifetimes. Similar arguments can be provided for Scala and Kotlin with their more functional syntax.
The thing that C/Go authors brought in straight from the seventies: utter garbage naming of identifiers.
But then again, the name of the language itself should be warning enough.