Significance of Go — Part 3 (Variables, Pointer Arithmetic and Constants/iota)
In the previous article, we learned how to play with VS Code along with Go and an introduction to packages and modules. In this article, I will be highlighting declaring variables in Go followed by the assistance for pointer arithmetic in Go. After that, I will be discussing constants and will introduce special usage of iota with simple examples.
Variable Declaration
Variable declaration can be done in three ways in Go as shown below.

The most popular method is Method 3 where you do not explicitly define the type of the variable.
No Pointer Arithmetic
Consider the below Go code.
package mainimport (
"fmt"
)func main() {
var m *int = new(int) *m = 100 fmt.Println(*m)
}
If you run the above code you will get the output as 100 as shown below.

The meaning of the above code snippet is to dereference the value stored in m (which was symbolized as *m) and print it. (Refer here to learn more about pointers in Go)
But consider the below code where you try to increment the pointer.
package mainimport (
"fmt"
)func main() {
var m *int = new(int) *m = 100 fmt.Println(*(m + 1))
}
This will give you an error as shown below.

The above code segment tries to deference the memory address of m incremented by 1 and prints the content inside that memory address (*m+1). In C, you can do it. This is called Pointer Arithmetic. But in here it has failed.
Go does not support pointer arithmetic which is in fact a plus point which makes Go less error prone.
No Implicit Type Conversions
Consider the below Go code segment.
package mainimport (
"fmt"
)func main() {
var i = 100
var j = 3.14
fmt.Println(i + 1)
fmt.Println(j + 1.3)
}
If you run the above code you will get outputs as 101 and 4.44 as shown below.

What happened here was, when the compiler is doing the compilation, each time it decides the type of the constant by itself. It means,
- In line 11, it decides that i is an integer and adds 1 to it
- In line 12, it decides that i is a float and adds 1.3 to it
But consider the below code segment. Run it and see what happens.
package mainimport (
"fmt"
)func main() {
var i int = 100
var j float32 = 3.14
fmt.Println(i + j)
}

The above code segment gives an error as shown in the screenshot. The reason for that is,
Go does not support implicit type conversions like in C, C++ or Java
In the above code segment, we tried to add an integer and a float. If we use a language like C, C++ or Java, the compiler will automatically convert smaller types to larger types whenever you mix them in any operation. The reason for not having implicit type conversions is as follows. (Refer here for more information)
The convenience of automatic conversion between numeric types in C is outweighed by the confusion it causes. When is an expression unsigned? How big is the value? Does it overflow? Is the result portable, independent of the machine on which it executes? It also complicates the compiler; “the usual arithmetic conversions” are not easy to implement and inconsistent across architectures. For reasons of portability, we decided to make things clear and straightforward at the cost of some explicit conversions in the code.
So the solution is to do explicit type casting. Consider the below example.
package mainimport (
"fmt"
)func main() {
var i int = 100
var j float32 = 3.14
fmt.Println(float32(i) + j)}
Now you will get an output like below.

In line 11, we have explicitly done the type casting which makes the code work. This is called explicit type casting. You can see that Go only supports explicit type castings but not implicit type conversions.
iota
iota is a keyword that can be used to assign to a constant, which represents successive values of integer constants (including 0). Consider the below example code segment.
package mainimport (
"fmt"
)func main() {
const (
zero = iota
one = iota
) fmt.Println(zero, one)
}
The above code segment will give you an output as below.

As you can see, the variables zero and one have been assigned successive numbers starting from 0. You can write the above code segment simplified as below and it will give you the same output. Try it and see!
package mainimport (
"fmt"
)func main() {
const (
zero = iota
one
) fmt.Println(zero, one)
}
Note:- As you can see in the above code segment, you can group multiple constants and define them using parenthesis.
Now consider the below code segment. Can you guess the output of that without looking at the answer?
package mainimport (
"fmt"
)func main() {
const (
one = iota + 1
_
three
) fmt.Println(one, three)
}

What happened here?
- In line 9, we have incremented the iota by 1 and assigned it to one.
- In line 10, we use an underscore to skip the next iota value which is 2.
- In line 11, three will get automatically assigned 3, because 2 was skipped in the previous line.
Now consider the below code segment.
package mainimport (
"fmt"
)func main() {
const (
one = iota
two = iota
) const (
three = iota
)
fmt.Println(one, two, three)
}
You will get the output as 0, 1, 0 not 0, 1, 2.

The reason for the about output is, when you have separate const blocks, the iota value will start from the beginning.
Conclusion
We can summarize what we have learned from this article as below.
- There are 3 ways to declare variables in Go
- Even Go has pointers, it does not support pointer arithmetic
- Go does not support implicit type conversions, but we can do explicit type casting when necessary
- Features and use cases of iota
See you later with another article on the significance of Go. Until then Goodbye!