Golang Code : Review Guides
Issues found Frequently
- New lines
- Double newlines
- No space after
//
- DRY principle violations
- Magic String/Number
- Error Shallow
- Naming convention not following
Guides
- [General] Never submit comment code-
- [General] Commnet should have space after
//
, eg. // This my comment
not //this is my comment
- [General] Naming convention must.
- [General] Every variable should be assigned only once, the best case senario. Try to have const or immutable object.
- At the worst case can be a loop take data or slice appending item can have multiple assigns.
- Or also, if variables changed, it should be done in one method, not in multiple.
- Except for the design pattern implementations
- [General] No magic string, or number, make constant for each magic number or string. ("β¦anything", 1, 2). Use constant to resolve this review rejection. Unless language has some sort of overruling.
- [General] There should be a newline (New Line Code Style Examples)
- [General] After any curly brace
}
, but not with consecutive ones
- [General] After
comma [,]
, if there is more than 2 parameters or arguments in function calling or in function definition or contructor injection or in property assigning. (JavaScript can have some exceptions, will be added in future.)
- [General] Before any return if there are multiple lines in the method or within the block.
- Exception: If a single line in the method then no newline before.
- Exception: If any
if
statements returns and there is a single line in it then no newline. However, if the if
statement block contains more than one line, there should be a new line.
- No new line (New Line Code Style Examples)
- [General] Consecutive curly braces or parentthesis.
- [General] After Return Statement
- [General] After Newline (that mean no double new line in the code)
- Function guideline must
- [General] Avoid multiple nesting or branching, to resolve this we can use function or inversing logic or taking variable approach.
- [Golang] DON'T use more than one
defer
in one function as defer works as stack
and it becomes complicated in future code maintain. If use it use it, on top or bottom.
Function Guideline
Function should be small, follow these principles DRY principle and SOLD principle wiki SOLID.
- [Golang] Should have proper naming, what it returns.
- [General] Function should not(β) exceed 3 arguments or parameters.
- Exceptions :
- Frameworks can have more (β
) than 3 args it is fine.
- Frameworks need to fit all kinds of things, thus it can have it.
- [General] Method Documenting: Usually simple methods doesn't require method documenting. However, if a method is doing something different (bad practice) or something implicit (bad practice) which cannot be directly explained with the naming then method documenting is a must. (The best approach is always to explain everything in naming if possible), these below cases method documenting is good and must.
- Golang:
- [Golang] Getters:
- Should have
Field()
not GetField()
- [Golang] Setters:
- Should have
SetField(..)
not Field(...)
- [General] Any other method name can have Get which is fine.
- [Golang] Constructor methods always starts with
New[StructName]
- [General] Try not to return more than 2 objects.
- [General] Try to have less than 8 lines of code in one method, at worst case, the scenario could be 15 lines, and the method should not exceed 25 lines (which can be referred to as
broken-fix-code
).
- This can be overruled while creating a framework function or some function that is memory intensive and require optimization. Making small function adds more function stack, thus memory cost and CPU counter cost as well.
- [Golang] Exporting / public method should have
CamelCase
.
- [Golang] Non exported / private methods should have
lowerCamelCase
.
- [General] (Doesn't apply in golang) to apply SOLID easily:
- Every class should be inherited from at least a single Interface and a single interface should hold only a single method.
- Now class which requires more than one method should inject or requires those interfaces of methods which required to be available in the class.
- This class will be in solid principal and will be short less than 60 lines of code and maintainable.
- [Golang] Unit-Test names should start with
Test...
Naming Convention
- [General]: Can always be overridden by Project guidelines or needs or reviewers preferences.
- [General]
Is...
, Has...
, Can..
, Should..
, (lower priority at the end Does..
) methods or variables should always returns a bool.
Is...
is highly recommend unless it doesn't go with the grammar (or may sound odd with Is...
then other versions are recommended line Has...
or Can...
).
- [Golang]: Don't use any underscore anywhere.
- [General] Singular item variable should NOT have plural symbol like
es
,s
or something like plural that represents multiple (array
, list
, vector
, slice
, enumerable items
, iterable
) things.
- Example: a single person object should NOT be named as people, or persons, it should be named as
employeePerson
or something similar to that.
- Exception case can be
OsGroup
, as OsGroup
can be represented as a single item, like UnixGroup(Mac, Linux,..), WindowsGroup, in this case, the group is name is appropriate.
- When we say
OsGroups
, it should represent an array of OsGroup
items
- [General] Multiple item variable ( refers to
array
, arraylist
, linked list
, list
, vector
, slice
, enumerable items
, iterable
) things should NOT have singular symbol like result
, person
, employee
but plural like results
, people
, OsGroups
- [General] If we have a map then it would be better to represent it with
resultsMap
as the naming suggest what we are dealing with in the future.
- [Golang] Variable naming:
- lower camel case: helloWorld not helloworld, hello_world
- no underscores
- [Golang] Const naming:
- Camel case: eg.
HelloWorld
, NOT (helloWorld
, HELLOWORLD
, HELLO_WORLD
, hello_world
, helloWorld
)
- no underscores
Package naming convention (golang-package-naming)
- lowercase all: eg. helloworld not helloWorld, hello_world
- should not have like package/package, that means, we are expecting a package name
taskrunner
we should not have methods taskrunner.taskrunner.DoSomething()
. Go naming should be taskrunner.DoSomething()
- folder and file name:
- It can be camelcase or all lower case or having hyphens or having underscores for test files.
- I would prefer hyphens over others (eg. underscore, camelcase) for folder and file names, which looks good, in terms of GitHub.
Make member - Lazy or LazyExecution πΌπ
Lazy means doesn't execute until needed. Don't be hungry. Lazy codes acts as caching. Basic principal in caching (Generate once and serve same data to many.)
Lazy should be applied on fields (any of the cases):
- Heavy lifting code or heavy process.
- Static value, doesn't change.
- Or, Same data is asked by everyone.
- 60%+ cases don't need to execute at all.
Lazy should NOT be applied:
- Code is changing repeatedly. Data is not same as per request.
- Func may require param to serve different things.
Examples of usecase
- Database query could be lazy. Only excute at the final stage
- Builder patterns in most cases lazy, takes instructions and executes by Build Command at last.
Converting from NonLazy to Lazy Code
- Make non export field, expose as getter.
- In the getter method check with flag or nil that the member is not generated.
- Generate member in the if block and then assign to the non export field and return the field.
- In case of working with slice or array, use lock mechanism using mutex.
- Everytime the field is in used should be called from the method NOT the direct field.
- If the required field is lazy, the current field should be lazy as well.
FROM
TO
Lazy Code References
How to use Regex in Golang
Regex is complex and usages backtrack programming to find matches, it is extremly expensive. It should be delt with care and caution. Regex should be the last resort of programming to detect some pattern in string.
Regex should NOT be used:
- Searching dots or comma and then trimming each word.
- Search for specific text in each line.
- Search starts with for each line.
- Search for ends with in each line.
- Search number in line.
- It depends if something is common then first cut out the specific part of the string which is common and then apply the regex on the dynamic string to find the pattern.
Regex should be used (must use with care):
- Search dynamic text with pattern.
- Code or syntax parsing.
- Ignoring whitespace and finding a match with required pattern.
- Where searching becomes too complex with for->for->for like bigO(n^3) then must use regex.
How to use it
Using Newline in Output or Splitting Confusing
It is confusing to use which newline from constant should be a priority and what to use. As os, has specific new line standards (Windows - "\r\n"
and Unix "\n"
)
In 90% of the cases, NewLineUnix (constants.NewLineUnix
) should be used. The only case, where constants.NewLine
should be used where we are asking the user for NewLine preference based on Operating System. An example from IDE can help understand this


If a file has \r\n
and if we read using \n
, problems can remain depending on the requirements. However, if we are parsing parse only lines without whitespace then it can be fixed at some level.
Choosing a newline preference always depends on the situation. In most cases, we should use \n
constants.NewLineUnix
It is still debatable and can differ.
Draft Notes
New Line Code Styling
- No new line in between curly braces if there is no code
- No new line in between curly braces if there is no code
- No new line at the start of the function or double new lines together
Multiple nesting avoid examples
Issue with nesting
Code nesting or branching makes the code complex (even if it is simple), consequently, we should always avoid code branching or nesting at our best. It helps to write simple unit tests and improves code maintainability in future.
Issue occur: Multiple levels of code nesting or branching using if
s, it can also be for
, if
, while
or other blocks nesting.
Exception case, it is quite alright to have one loop and then a if
statement branch. But not more than that. Moreover, to be specific this exception case doesn't apply on multiple if
statements.
To resolve this issue we can use, we can use any of the below methods
Resolve nesting using method
Resolve nesting using inverse logic
Notes: We haven't used the else part the in the last return because it is redudant. We should always try to avoid else
if it is not necessary.
Example of Resolving Nested branching on Complex Code (level 4 to level 1)
Resolve nesting using inverse logic, variables and ternary operators
Golang doesn't have any ternary operators so assume that it has and the process may look like this below:
Avoid else
if not necessary
- Should NOT call directly a return value from a function unless it is a constructor or gurateed to have the result except
nil
.
- Every return pointer value should be tested not nil before calling or access any member (field or function / method) of the struct.
- Before making a variable to pointer, must check if the variable is not nil.
- Every array should be tested with nil before access any index or itself.
- Any pointer acessing should be checked with not nil.
, Or
Note: Handle error with panic, not appropriate here in terms of naming.
Code Mutation (Dangaours Issue, code RED) Avoid and Example
Code mutation, refers to the variable modification, which violates the code review rules (as no variable or things should be changed and should be assigned only once). At the wrost case senario it can be only applied for caching a variable or lazy instanciation / evaluation where an execution requires a for-loop or many checking which will be same after the first time checking then there is no point of running the same thing more than once but cache it using a variable. In that case we can mutate a variable. Keep in mind mutating a variable requires mutation lock, or else it will fail in asyc / gorountine environment. Plus, also keep in mind that adding a lock is also expensive. One can solve it with two ways (a. Lock version of the method b. non lock version of the method). So for example, if a method does GetLines (example can be obtained from strhelper) which is the non lock versin, another version could be GetLinesLock() ->
Returning variable, updated multiple times, can be fixed.
Current version (with mutation issue)
Fixed code mutation (eg. # 1)
Fixed code mutation (eg. # 2)
Cheat Sheets
Strings in GO

Note: In Go Strings passes by Reference, but the struct gets copied which has length and bytes to pointer.
Slice
Slice Struct
Code Red
Dangerous