DEV Community

Cover image for Getting Going with Go, Day 4
Kai
Kai

Posted on

Getting Going with Go, Day 4

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:

>>> a = "bc"
>>> a
'bc'
>>> a = 3
>>> a
3
Enter fullscreen mode Exit fullscreen mode

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:

package main

import "fmt"

func main() {
    a := "bc"
    fmt.Print(a)
    a = 3
    fmt.Print(a)
}
Enter fullscreen mode Exit fullscreen mode

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?

package main

import "fmt"

func main() {
    a := "bc"
    fmt.Print(a)
    a := 3
    fmt.Print(a)
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

package main

import "fmt"

func main() {
    a := "bc"
    fmt.Print(a)
    var a int
    a = 3
    fmt.Print(a)
}
Enter fullscreen mode Exit fullscreen mode

No dice:

./prog.go:8:6: a redeclared in this block
    previous declaration at ./prog.go:6:2
Enter fullscreen mode Exit fullscreen mode

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. 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()):

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)
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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

Top comments (0)