Getting Going with Go, Day 4
Tags: go, codenewbie, 100daysofcode
Published: 2021-01-28 20:28:01

Today I thought I’d look into static typing of variables, as it’s a fundamental quality of Go as a language.

So, in languages like Python, you could very easily do the following with variables:

```python
>>> a = "bc"
>>> a
'bc'
>>> a = 3
>>> a
3
```

In languages such as these, a variable is just a container for *stuff*. You can change what stuff goes in mid-stream, dynamically changing the type of the variable.

In comparison, Go is a statically typed language. You can either declare a variable explicitly with its type for use later (`var x int` for integer) or inferred at creation time (`x := "hello"` for a string containing “hello”) So of course I’m going to try the same exact hijinks as above:

```go
package main

import "fmt"

func main() {
	a := "bc"
	fmt.Print(a)
	a = 3
	fmt.Print(a)
}
```
Trying to build or `go run prog.go` spits out an error message:
`./prog.go:8:4: cannot use 3 (type untyped int) as type string in assignment`

Okay. But what happens if we try to dynamically reassign to the existing variable `a`?

```go
package main

import "fmt"

func main() {
	a := "bc"
	fmt.Print(a)
	a := 3
	fmt.Print(a)
}
```

Unsurprisingly, we get the same error as before, but also a complaint about trying to assign a variable using the type-inferring `:=` operator:

```
./prog.go:8:4: no new variables on left side of :=
./prog.go:8:4: cannot use 3 (type untyped int) as type string in assignment
```

OK, so what if we redeclare the variable as a different type after we use it?

```go
package main

import "fmt"

func main() {
	a := "bc"
	fmt.Print(a)
	var a int
	a = 3
	fmt.Print(a)
}
```

No dice:

```
./prog.go:8:6: a redeclared in this block
	previous declaration at ./prog.go:6:2
```

Just as an aside, what I do really like about the stack trace here is that it doesn’t just bomb out with “type mismatch” or whatever. It’s actually quite friendly - it tells us that on line 8, position 6 a redeclaration of a variable occurs, and even where it was originally declared.

### But why all this hassle about typing? I just want to cram stuff into my variables

The reason for static typing is, unsurprisingly, [efficiency of execution](https://hackernoon.com/i-finally-understand-static-vs-dynamic-typing-and-you-will-too-ad0c2bd0acc7). Because the program isn’t constantly checking the type of information in variables that it processes to see what it can do with them, it’s simply faster to run. This plays right into the fact that Go is a compiled language, so all of that checking and translation into machine code is done once at the compilation stage, not every single time the program is invoked. Efficiency!

So, while it makes little sense to have your little script that you use to sift through information that you pass it on occasion written in Go, if you’re having something chomp on lots of data or be invoked lots of times, the efficiencies become clear.

But there isn’t one type of programming paradigm that’s dominant at the expense of others. If all you have is a hammer, then everything looks like a nail. You’re going to need the right tool for the right job, and statically typed and compiled languages like Go are the right tools for particular jobs.

## Getting information out of variables

Let's declare a few variables and use Go's syntax of printing information about them (`fmt.Printf()`):

```go
package main

import "fmt"

var (
	DemoString string  = "Hello, world!"
	Boolean    bool    = true
	FloatingPt float32 = 1234.567
)

func main() {

	fmt.Printf("DemoString is a variable of type: %T. It has the value of %v", DemoString, DemoString)
	fmt.Printf("Boolean is a variable of type: %T. It has the value of %v", Boolean, Boolean)
	fmt.Printf("FloatingPt is a variable of type: %T. It has the value of %v", FloatingPt, FloatingPt)
}
```
This gets you:

```
DemoString is a variable of type: string. It has the value of Hello, world!
Boolean is a variable of type: bool. It has the value of true
FloatingPt is a variable of type: float32. It has the value of 1234.567
```

It's important to note here that you *cannot* print the name of a basic declared variable in Go. As the human-readable names are discarded at compile time, you're left with just their values and types. That's why in the above example I had to manually put the name in to the string I was printing, and then get the value and type from the program itself. Also notice that the interpolation proceeds left to right with references at the end of the line, so for every interpolation you have to declare the variable to be used at the end of the expression.

## References and further reading

- [A Tour of Go - Basic Types](https://tour.golang.org/basics/11)
- [I Finally Understand Static vs Dynamic Typing and You Will Too!](https://hackernoon.com/i-finally-understand-static-vs-dynamic-typing-and-you-will-too-ad0c2bd0acc7)
- Cover image: Photo by [Mika Baumeister on Unsplash](https://unsplash.com/@mbaumi?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

Tomorrow, who knows? It’s a Friday, so I might be doing this with a glass of wine…