I have seen a lot of Java/Python/C code written in Go. When you start off from a different language, all the freedom you receive seems daunting. You face issues while you are developing and take shortcuts, so you can finish faster. Don’t do it. Future you will hate you, your colleagues will hate you, and I will definitely think less of you.
This list is definitely not complete, just something that would have helped me as a beginner Go developer. It is also very subjective, and exceptions do exist.
The init() function
Don’t use init(). It complicates the flow of the program. It’s extremely hard to debug, and there is usually a better way to get the same result.
Most of the times I have seen init(), there was a function giving you a NewInstance(…) of the struct defined in the same file. Why not add the code from the init() into this NewInstance(…)?
I have also seen init() in the folder with the main function. Usually, there’s some code to read environment variables or initialize some other variables. So basically code that could be easily added to your main() function.
There are legit usages of the init() function too. It is powerful. In case you are writing code to be imported, and there’s a need to initialize something before any of the functions are called – yes, it is nice to have it around. Just don’t overdo it.
Handling environment variables
Only read from environment variables in the main function, or when you start your application. You could also add it to the code that creates a New instance to the struct. But again, that makes the flow so complicated. You don’t want a complicated flow. You want something easy to understand so future you will be able to debug it. Plus testing a code that’s using parameters is much easier.
panic() and os.Exit()
Only panic(…) or os.Exit(…) in the main function. You want to catch those errors, wrap them, and print them out nicely. You don’t want to wake up in the middle of the night during your on-call shift and debug cryptic errors printed somewhere hidden deep inside your Kubernetes cluster. Yes, it is not an easy job to handle errors elegantly, but do invest the time and effort to think about them. Future midnight you will be thankful.
“utils” package
Don’t use generic package names like “utils”. You wrote a function sorting a list? Good for you. Leave it where it is used, or maybe in the file that declares the struct present in the list.
You really should not use random package names, everything should have significance.
TODOs
This is not Go-related, just something that keeps your code clean. Every TODO should have a link to the follow-up ticket ID. If there’s no ticket, it’s probably not important enough to get it implemented. You could also explain why the shortcut was better than the implementation in a comment.
Always refactor
This is an important thing I have learnt at my last job. “Always leave the code better than you found it.” (Uncle Bob) Add tests. Rewrite small pieces of code you added a few months ago when you did not know better. Delete parts that are not needed anymore. You should be always in the “improvement mode“. Also, don’t take shortcuts when you add new functionalities, it will bite you in the butt. This is also not Go-related, but something I feel is important.
I hope these points can give you some ideas on how to improve your code. Or at least they make you think. I have a post planned on Go project structures as well. Go is a beautiful and versatile language – but I love it mostly because of its minimalistic nature. Keep it clean and efficient!
No comments:
Post a Comment