One should not be afraid of making mistakes because mistakes are the stepping stones that take you to your destined heights. However, one should not repeat mistakes, and in case they do so, that is the biggest mistake. It’s best if you learn from other’s mistakes and capture them forever.
I’ve brought for you the common Go programming language mistakes that Gophers have claimed of coming across. After all, Golang Web Development is Better Than Other Programming Languages in 2020.
Though being popular and trendy, Go developers often face specific common bugs or errors. Programmers popularly address them as Gotchas.
Golang is a comparatively new programming language by Google. Naive Gophers often come face to face with these pitfalls, so I thought to disclose them to you. Check out the Gotchas that I have collected for you. And if you have already come across them in your Go programming journey, well and good. If not, then my experience is going to help you.
To all my Go friends, you can take this as a challenge from me! Check out all the 24 common mistakes in Go or Go gotchas and comment if you have come across all of them on your own. Well, also do comment if you have any other such gotchas that are new to me, that I haven’t mentioned.
1. Entry in nil Map
While using maps in Go language, first-time Gophers are going to come across this abrupt behavior.
Once you define a map in Golang, your program will result in a panic statement.
At such times, you need to initialize your map using the make function, like this:
You can alternatively also use a map literal. Problem Sorted.
2. Nil pointer dereference
Go-developers many a time face the issue of dereferencing of a nil pointer. Check out the problem.
As the pointer in the main function (p) is nil, you can not follow the nil pointer because it causes a run-time error.
You can either create a new Point like in the above snippet.
Methods with pointer receivers either need a value or a pointer, so try this way out:
3. Multiple-value in single-value context
As you try to parse the date and time, you get a compiler error.
The parse function with time returns a time value and an error value, and you need to use both explicitly.
To ignore the unwanted error values, you can use a blank identifier _ as below:
4. Unchangeable Array values
In Go programming language, developers often complain that array values stick.
To overcome this gotcha, you should use a slice because arrays in Go are values.
slice refers to a section of an adjacent array, and one can change the array’s values using it.
5. Shadow variable
The value of a variable remains unchanged even after applying increment ++.
Such abrupt output results because the value of n is shadowed when you say n := 0, throughout the ‘if scope’.
To effectively work out your way from the above gotcha, you should simply write n = 1.
To use shadows in your Go code, after version Go 1.12, include this code in your program:
However, the compiler of Golang does not allow precise shadowing, like here:
6. Unexpected new-line
Sometimes naive Gophers face a weird compile-time error of missing comma or an unexpected new-line.
The thumb-rule is that every line in a multi-line array or slice should end with a comma.
Hence, you can alter the code without tempering the rest of the surroundings. Issue solved.
7. Unaltered strings
The above code doesn’t compile.
Strings in the Go programming language are immutable. Consider strings as read-only byte-slice, and hence you should instead use rune slice.
However, if your string contains ASCII values, then you can use a byte slice.
8. Print favorite band name ABBA
Here’s something you must know about the trim function of Golang.
The trim function strips all the Unicode points in a cutset. In our code snippet, the trailing A and B are removed from the string, leaving an empty string behind.
To overcome this flaw, use TrimSuffix, and you can see favorable results.
9. Missing Copy
The copy function in Go copies minimum elements of the source to the destination.
To ensure correct copying, you should allocate sufficient destination slice. Check out:
The copy returns the number of elements copied.
You can alternatively use the append function in Go to copy array elements.
Mark that the size of the append slice will be larger than the length len(src).
10. Append issue
There is an uncertain output of the append function.
To understand the behavior of append, consider the following snippet:
a1 and a2 are the same in our example. Therefore, you must use individual byte arrays:
11. Unexpected ++
Some Gophers face troubles with the pre and post incrementation.
In the Go programming language, you can use increment and decrement operations as statements and not expressions.
You can check out the official Go FAQ.
12. Clash of Go and Pythagoras
Let us perform the Pythagoras theorem, a2 + b2 = c2.
Taking another case, 6, 8 & 10, is another Pythagoras triplet. But while performing the function in Go, it doesn’t agree.
This malfunction occurs because the ^ symbol indicates bitwise XOR, unlike base to power 2.
In the case of 1+6=7, Pythagoras luckily turn true, but not always. So, to raise a number to the power of 2, use multiplication, as shown below:
Tada! There’s a solution to every problem.
13. Infinite Loop
This loop goes infinitely, without a break because b++ is under execution after b = 255, which is the maximum value a byte can hold. The loop restarts from b = 0 because b < = 255.
You can try using strict inequality but in vain.
One way to overcome this is by using int type.
Another way is to put a test to terminate the loop:
We are good to go.
14. Number starting with 0
Golang’s newbies think that the language is not good with counting. Here’s why.
This issue rises because octal literals start with 0.
Go does not support negative decimal numbers, nor decimal zero integers.
15. Negative Remains
Unlike the rules of Mathematics, negative dividends can yield a negative remainder in Go.
If n is an odd negative number, n % 2 results in -1. However, you can overcome the problem like this:
Alternatively, you can use the bitwise AND (&) operator.
And you are sorted. Clear and straightforward.
16. Time and Number are separate entities
You can not mix numeric types in Golang.
To work out the above code, you have two options. Either multiple with the same type or with an integer of no type.
Now you are good to go.
17. Index out of range
Indexing starts from zero in Go.
This program crashes.
The values of a are placed at a, a, a, …….., a[len(a)-1].
You can use a range loop:
And you get what you need.
18. Range Loop uncertainties
You need to understand how the range has two values, an index, and other data values.
This program prints the array indexes instead of the values.
Directly use the second value (data) of the array by omitting the index.
Oh, please don’t thank me!
19. Changing range loop entries
Your range loop takes the help of a local variable to store iterations.
You can access the iteration variable to get the desired output.
20. Iteration variable of range loop unchangeable
The iteration variable is unaware if an array value changes.
You can iterate the values over a slice instead of the array.
21. Closure and Iteration variable
There arises a competition between two goroutines when they access the same variable simultaneously, and one of the accesses is ‘write’.
This snippet produces this print output.
Here, a variable i is accessed by six goroutines. So, instead of i, you can use a local variable n:
To avoid this data race, too, you must use a unique variable for each goroutine.
A sigh of relief!
22. JSON not visible
You unexpectedly get to see an empty JSON object in Go.
You need to export your JSON values.
Make use of naming the JSON values with a tag.
23. Regular expression mismatch
While using Go, most of the regular expressions function in the package use substring matching.
It matches the characters in the string, which we do not intend.
To overcome the bug, you can anchor the beginning and end of the string with caret ^ and dollar $ signs.
Now you know how to work magic with words, even in Golang.
24. Nil is not equal to nil
In Go, an interface equals another interface, only if both their concrete and dynamic values are the same. The same applies to the nil value.
As you can see, the function Foo() returns nil whereas, we compare it with os.PathError which is not equal.
In Golang, an interface with value and type nil is not equal to another interface whose value is nil, but its type is not nil.
To overcome the nil type mismatch, if we convert the nil to its correct type, like this:
We get no errors.
Another approach to solving this problem is to use a variable with a type error. Just as we show here:
However, the best practice is to use the in-built error interface type instead of a concrete one, to save and return error values.
With this last Go gotcha, I conclude my post.
I hope you found my collection worthy, and these gotchas will help you learn from my common mistakes in Go programming. Do share your experience with such gotchas in the comments. And also share this blog with your peers and friends, if you please.
At Bacancy Technology, we aid you in robust development and cross-platform support with our mastery in multi-threaded and parallel processing. We offer end-to-end full-stack Go development expertise to build your scalable web architectures. Get in touch with us, the globally renowned Golang development company, and save upto 40% on your future project costs. We also offer a 15-days free trial along with our Agile Software development process.