November 27, 2020

24 Common Mistakes In GO (gotchas) And How To Avoid Them

Source

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 mistakes in Go programming language 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.

Gotchas are the abrupt parts of your program structure that make your code prone to mistakes and errors in your program execution. Gotchas are counter-intuitive, and it is not possible to avoid or spare them.

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.

Top 24 Common Mistakes in Go

1. Entry in nil Map

While using maps in Go language, first-time Gophers are going to come across this abrupt behavior.

The issue:

Once you define a map in Golang, your program will result in a panic statement.

Solution:

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.

The Issue:

As the pointer in the main function (p) is nil, you can not follow the nil pointer because it causes a run-time error.

Solution:

You can either create a new Point like in the above snippet.

Or

Methods with pointer receivers either need a value or a pointer, so try this way out:

3. Multiple-value in single-value context

The Issue:

As you try to parse the date and time, you get a compiler error.

Solution:

The parse function with time returns a time value and an error value, and you need to use both explicitly.

Or

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.

The Issue:

Solution:

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 ++.

The Issue:

Such abrupt output results because the value of n is shadowed when you say n := 0, throughout the ‘if scope’.

Solution:

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 Issue:

Solution:

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 Issue:

The above code doesn’t compile.

Solution:

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 Issue:

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.

Solution:

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.

The Issue:

Solution:

To ensure correct copying, you should allocate sufficient destination slice. Check out:

The copy returns the number of elements copied.

Or.

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.

The Issue:

Solution:

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:

Fixed.

11. Unexpected ++

Some Gophers face troubles with the pre and post incrementation.

The Issue:

Solution:

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.

The Issue:

Solution:

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

The Issue:

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.

Solution:

One way to overcome this is by using int type.

Or

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.

The Issue:

Solution:

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.

The Issue:

Solution:

If n is an odd negative number, n % 2 results in -1. However, you can overcome the problem like this:

Or

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.

The Issue:

Solution:

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.

The Issue:

This program crashes.

Solution:

The values of a are placed at a[0], a[1], a[2], …….., a[len(a)-1].

Or

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.

The Issue:

This program prints the array indexes instead of the values.

Solution:

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.

The Issue:

Solution:

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.

The Issue:

Solution:

You can iterate the values over a slice instead of the array.

Woohoo!

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’.

The Issue:

This snippet produces this print output.

Solution:

Here, a variable i is accessed by six goroutines. So, instead of i, you can use a local variable n:

Sorted result:

Or

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.

The Issue:

Solution:

You need to export your JSON values.

Or

Make use of naming the JSON values with a tag.

Issue fixed.

23. Regular expression mismatch

While using Go, most of the regular expressions function in the package use substring matching.

The Issue:

It matches the characters in the string, which we do not intend.

Solution:

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.

The Issue:

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.

Solution:

To overcome the nil type mismatch, if we convert the nil to its correct type, like this:

We get no errors.

Or

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.

Conclusion

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.