Few little things in Go

Nenad Ticaric
2 min readJul 27, 2020

--

While writing programs in go, you’ll come across some weird situations where you don’t know why the compiler complains. Let’s take a look at some of those cases.

When you first look at that code, everything looks normal, but for some reasons, the compiler will complain, saying:

counter declared but not used

but why would the compiler complain if we see that the variable counter is used. It’s been set to 1 if the shouldStartWithOne() function returns true.
If you run it through a linter, you might get a more detailed explanation:

counter declared but not used (as r-values)

This means that each variable declared in a code block must be used as a r-value (right-hand-side value) for at least once.

Now, this might be clear to you, but in case it’s not, read on.

There are two types of expressions in Go, l-values and r-values

A l-value represents an assignable location that points to a memory location. They can appear both on the left and on the right side

The r-value represents the actual data that is stored at some address in memory. You cannot assign a value to it, which means it can appear on the right, but never on the left

With this understanding and with a little change we can make the above code work

_ = counter

To make it short, you cannot just declare a variable or assign a value to it, you have to use it. Either assign it to something else, or pass it to a function.

After reading the documentation, you’ll find out that the if statement also accepts a initialization statement, which is cool. It lets you write something like this:

if err := file.Chmod(0664); err != nil {
log.Print(err)
return err
}

You also may know that a map lookup returns two values, the second is a boolean that reports whether the element was present in a map or not. This brings us to writing code like this:

if elem, ok := elements["something"]; !ok {    return nil, errors.New("element not found")}doSomethingWithElement(elem)

But for some reason, this fails by saying that elem was declared but not used.
The thing here is that the elem variable is only scoped to the if block, so it doesn’t exist outside of it. Alternatively, it exists in the else block.

if elem, ok := elements["something"]; !ok {    return nil, errors.New("element not found")} else {    doSomethingWithElement(elem)
}

So if you want your code to be nicer looking, you would do the lookup before the if block

elem, ok := elements["something"];if !ok {    return nil, errors.New("element not found")}doSomethingWithElement(elem)

Hope this article helps you to understand some of go’s behavior

--

--