Go for Developers: Setup, Variables, and Basic Types

Introduction
In the intro I discussed why fundamentals matter. Now let's actually start learning them. In this series I will outline main principles and first steps needed to get started.
Let's go.
Go is compiled directly to machine code. It is statically and strongly typed, and handles concurrency using Goroutines - lightweight concurrent functions managed by the Go runtime.
In a statically typed language, you must declare the type of a variable before using it. Strongly typed means the type of a variable is strictly enforced. Once declared, it cannot be used as another type. In Go, variable types are known at compile time, but the compiler can infer them for you.
Go was designed to be readable and unsurprising. Coming from dynamically typed languages such as JavaScript, you'll find a lot of familiar ideas: functions, loops, conditionals, but with stricter rules.
Setup Environment
To set up the environment and install Go on your machine, download the package from official website and check version by running go version. Don't forget to restart your terminal to update PATH environment variable.
To initialize project and enable dependency tracking use
bash1# create project folder2mkdir my-first-go-app34# move inside5cd my-first-go-app67# initialize module8go mod init my-first-go-app
go mod init [module-path] will create a new module go.mod file at the current directory to track code's dependencies. In the beginning the file will include only the name of your module and the Go version.
Hello World in Go.
Now, let's say Hello World in Go. In your current directory create a file named main.go and write there:
go1package main23import "fmt"45func main() {6 fmt.Println("Hello, World!")7}
Compared to JS it looks massive:
javascript1console.log('Hello World');
What is going on there:
- Every Go file belongs to a package. Executable programs use package
main. main()is the entry point - just like in C.fmtis the standard library package. It contains functions for formatting text, including printing to the console.
Coming from JS, it's important to note that Go distinguishes between strings and single characters: the double quotes (" ") or backticks (` `) are used to create string. These are sequences of bytes (usually UTF-8 encoded text). The single quotes (' ') create rune. This represents a single Unicode code point (essentially an int32).
To compile and run this code, type in the terminal go run main.go to specify an entry point. Or use go run . to target the package in the current directory.
When you execute go run, the Go compiler creates a binary file in a temporary directory on your computer. It compiles the code, executes the resulting binary and immediately deletes the binary after the program finishes.
go run is intended for development and quick testing. To get the actual compiled executable file, use: go build main.go. It will generate executable file in your current folder.
Variables
In Go variables are declared with var. Their values can be changed after declaration. They can be declared in several ways and the way they are declared matters more than it might seem at first.
-
Explicit declaration with type
var x int. In this case,xis declared as an integer. You can declare this way, but if you don't use it later, your program will not be compiled. This strict rule applies to local variables. -
Declaration with initialization
var y int = 10. Here,yis declared as an integer and initialized with the value10. -
Type inference: Go can infer the type of a variable if it is initialized with a value
var z = 20. The type ofzis inferred asint. -
Short Variable Declaration. It only works inside functions. In short declaration Go infers the type automatically. You still cannot change its type:
a := 30. Here,ais declared and initialized with the value 30. The type ofais inferred asint. -
Multiple variable declaration:
go1var (2 b int3 c string = "hello"4)
In this example, b is declared as an integer, and c is declared as a string with the value "hello".
- Short Declaration for Multiple Variables:
go1d, e := 40, "world"
Here, d is declared as an integer with the value 40, and e is declared as a string with the value "world".
Zero Values
Unlike JS where uninitialized variables are undefined, Go variables always have a zero value:
go1var i int // 02var f float64 // 03var b bool // false4var s string // "" (empty string, not nil!)5var p *int // nil (for pointer types)
They say it eliminates a whole class of bugs around uninitialized state.
Constants
Constants declared with const are immutable. Once declared, their values cannot be changed. Constants must be initialized at the time of declaration and cannot be modified later.
Used for values that should not change throughout the program, such as configuration values, mathematical constants, or fixed settings.
go1const Pi = 3.141592const AppName = "mytool"3const MaxRetries int = 3
Basic Types
We already know that Go is statically typed, meaning that once a variable type is defined, it can only store data of that type. Go comes with a set of built-in types. You can also define your own. Here is the top-level split:
text1All Go Types2├── Built-in Types (predeclared by the language itself)3│ ├── Basic Types4│ └── Composite Types5└── Defined (Named) Types6 ├── Type Definitions7 └── Type Aliases
Types are a very vast topic in Go, let's just look at some basic types.
go1// Booleans2var isReady bool = true34// Integers5var count int = 426var port int32 = 80807var big int64 = 900000000089// Unsigned integers10var id uint = 11112// Floats13var price float64 = 9.9914var ratio float32 = 0.51516// Strings (immutable, UTF-8 encoded)17var lang string = "Go"1819// Rune (alias for int32 - represents a Unicode code point)20var r rune = '🚀'
Go has two categories of numeric types that differ in how their size is determined: fixed-size and platform-dependent.
The first type, a fixed-size type, means that the size of the data in bits does not change, regardless of the architecture of a machine that the code is compiled for. For example, using int32 ensures that the size of the integer is consistent across different platforms:
go1var count int32 = 42
The second type is a platform-dependent type. Its bit size is determined at compile time based on the target architecture and can vary from platform to platform. In this example it will be 32 bits when compiled for a 32-bit target, and 64 bits when compiled for a 64-bit target:
go1var count int = 42
For developers coming from dynamically typed languages, this is worth keeping in mind, because in dynamically typed languages like JavaScript, you never choose between int32 and int64. In Go, that choice is yours, and it has real consequences for cross-platform behavior.
In addition to data types having different sizes, types like integers also come in two basic types: signed and unsigned. An int8 is a signed integer, and can have a value from -128 to 127. A uint8 is an unsigned integer, and can only have a positive value of 0 to 255.
In the next article I'll proceed with types as they play a huge role in building a mental model of any language.