I have heard that it has faster compile times. I have heard that it's low-level. But I don't get why I should choose it over a language that I enjoy, such as C++ (for low-level control, particularly the modern incarnations of it).
Can you help me to understand what the killer feature of Go is and under what circumstances I should consider using it? Likewise, what would be a poor application of the language?
(Context: I'm not necessarily a language snob. I use C++, Python, JavaScript, Java, etc., and I know which I prefer for solving particular types of problems. I just don't understand why I might need Go. There's a longer story as to why I'm so concerned about using it or not, but that is for another time.)
Thanks for your comments!
Another thing about Go is that it is a balanced language in my opinion (both high and low level depending on use case). You can build a cli, a full stack web app or write low level network code. I love it.
I used it for pushing data around on a server and a cli. The easy concurrency was the killer feature for the server, and single binary distribution for the cli.
For the most part, the build process is very simple, no "dll hell".
Very stable API. With the Go 1 promise, code written 10 years ago still just works.
Others mentioned the statically linked binaries. That's huge. We compile a binary targeting Linux, throw it in s3, that gets pulled to production. Whole thing just works. No dependencies.
Killer "features" of Go:
- Very easy to get someone up to speed on it. I chuckle when I see positions advertised as "preferring Go experience". A good programmer can learn most of Go's features in a month.
- Makes a lot of "magic" impossible or so annoying as to be not worth writing. This means you can usually just read your dependencies' source code to easily figure out what they're doing. Nearly all Go code looks the same.
- Languages like e.g. Rust attempt to actually model certain problems accurately, which introduces a lot of unavoidable complexity. Go does not bother itself with such concerns as "correctness" in many cases. I sound snide but for many use cases this is the right move.
- Go moves slower and has a commitment to backwards compatibility that many other languages don't.
writing fronttend backend web apps? id go with typescript for react and nodejs.
writing scale efficient backend services, go or kotlin or java makes sense.
writing performance freak modules and software or embeddes or similar, go rust or cpp or c.
you wanna get down to the trade offs. where are you exactly in the stage of development, who your users are, the platforms you are targetting, such and such.
i use typescript. but my ts code imports uwebsockets.js which lets me use a web server written in cpp and c. for caching we use redis. for routing we use caddy.
you wanna take advantage of other languages and premade solutions by other people on where they excell.
A poor application of Golang that I have seen are full featured web frameworks like the ones you find in interpreted languages (Rails, Django, Lavarel, Phoenix, etc).
I feel like Ruby and Python are better & easier for applications that perform text ETL, text scraping, etc.
At the end of the day though, use whatever works for your style. C++ isn't going anywhere. But I am noticing a lot of people talking about the importance of type safety when Rust development was allowed in the Linux kernel.
- CGo as a bridge between C and Go/VM world
- go:embed and go:generate for bindings, preshipped modules and assets
- 100% static binary as simple as an environment flag
- golang compiler is self hosted in go, which means you can make malware that can make malware :)
- pretty much all operating systems or as close to it, without any host system requirement and neither dozens of compiler environments with outdated SDK headers
- go assembler, which ironically makes this the best language for malware development
- batteries included language, use golang.org/x and that is almost always anything you will ever need
- can be typesafe but also not ("unsafe" package), which is important for exploit development
- doesn't need 2 Million string abstractions (just kidding, rusties)
From a software architect's perspective:
- VERY opinionated language design, you have to set aside your personal opinion to be able to like it
- generics took a long while, now they're here but you still have to implement all yourself. Not there yet with forEach, map, reduce etc.
- Uppercase for export was a dumb decision, because serializer specific annotations to map field names is an effect for that cause
- standard formatting guidelines, use go fmt, don't use semicolons because nobody does
- for loops everywhere, which can be bad for readability compared to forEach() scopes
- no recursive dependencies, so you need to restructure your code
- embraces methods on custom structs as receivers, at least somewhat
- marshal/unmarshal is both a godsend when you are in control of the data and utter hell when you have to parse arbitrary JSON with multiple key/value types. E.g. maintainer field in package.json can be Array of Objects, an Object, or a String. Have fun in go with that one.
- reflect API is very painful, but it kinda always is in every language
Interfacing to hardware? Bit-flipping in registers on a peripheral chip? I'd use C++ for that.
Something with lots of dynamic memory usage? I'd at least consider Go because of the garbage collection. That makes an entire set of problems just go away.
Something with a ton of network connections? Again, I'd consider Go.
Something where I need the last drop of performance? C++.