Had a similar experience, but for me it was a little over 2 years ago and much of what you mentioned here struck me as well. Given that, I can share some extra ideas (and couple of unrelated random observations):
- the statically typed Go (it’s not Golang, not anymore at least) also helped pinpoint the inconsistencies that were downright stupid (at times) in some APIs I used (sometimes that even I created). Due to types, I ended up needing to convert between strings, int32, int64, etc. Choosing the type of my variables is one thing, but juggling the types mapped from outside sources was the real fun.
- observation: Go doesn’t do parallelism, not by default. What goroutines do is concurrency and there’s a pretty big difference. Go can also do parallelism (by default, under certain conditions)
- OOP: biggest thing yet. Go doesn’t have shortcomings because Go is not an OOP language. It’s a functional language, that’s how it was designed. It’s true that it’s generally a better fit for microservices but also it’s silly to say you’d have other expectations from a statically typed language. What’s one got to do with the other? Statically typed simply means that type of a variable can’t be changed, has nothing to do with the existence of interfaces or defining custom types.
- PHP also has a concurrency framework based on the concept of corouting which is close to goroutines, it’s called Swoole (might want to check it out)
- PHP also has an application platform that’s written in Go (called RoadRunner).
- PHP is not fit for microservices, not by a longshot (unless you use Swoole + Roadrunner). From dependency managed to runtime, the fact that it doesn’t daemonize properly, type safety, etc, even after 7.1 it still has running problems and performance problems that don’t make it suited to the low-latency high speed requirements of microservices (just a couple of years ago had as a microservice some queue workers from Laravel — easy to develop but slow, hard to debug, deployed codebase was huge and didn’t play well when being kept in memory so always had to technically restart the cli command)