This is the fourth post in my series of complaints about why Go’s time-saving features are actually long-term time-wasters. You can find links to the previous parts of this series at the bottom of the post. Today I want to talk about exporting names via capitalization.
In Go, you can export a top-level name from a package by capitalizing the first letter. If it’s not capitalized, it’s not exported. Simple, right? And very economical—there’s no need for additional keywords or other special syntax; just push shift when you type the first letter.
Unfortunately, this means that changing your mind about exporting a name isn’t simple any more. Instead of adding/removing a word like public in front or listing/de-listing the name in an export section, you now have to find all instances with the wrong case and change them. A simple string replacement won’t necessarily work because you might have substrings that match (e.g. changing fun() to Fun() shouldn’t change refund() or “this is fun”). You ideally need a syntax-aware refactoring tool instead of just a regex or a string replacement.
Even worse, you might have both Fun and fun already. Un-exporting Fun by renaming it to fun is now a symbol clash instead of just a rename. Normally, I would say that having symbols that differ only in case is generally bad style and I don’t have much sympathy for this breakage. Unfortunately, this usage is actually recommended by Effective Go to distinguish getters from their fields.
And there you have it: Another initially clever trick that saves the original author a few keystrokes by shifting potentially non-trivial work onto the subsequent maintainer.