Basics of Variables, Constants, and Data Types in Go
Exploring Variables, Contents, and Data Types in Go Programming

Search for a command to run...
Exploring Variables, Contents, and Data Types in Go Programming

No comments yet. Be the first to comment.
Go beyond the basics! This series explores how Go works under the hood — from memory management to goroutines, channels, and design principles that make Go ideal for modern backend development.
An Introduction to Go's Decision and Loop Features for Beginners
A Complete Guide to Go’s select Statement: Evaluation Order, Blocking, Timeouts, and Cancellation

The simplest way to understand Go's concurrency communication system

Exploring Key Features of the fmt Package in Golang

Understanding Goroutines: Key to Go's Concurrent Strength

Explore the Differences Between Multiprocessing and Multithreading for Better Performance

In the previous article, we installed Go on our system and ran our first "Hello, World!" program. Now, in this article, we will learn about variables and data types. This is an important topic because we need to store data in memory while running the code to reuse it throughout the program. To do that in Go, there are some rules. So let's dive deep into this.
A variable is a named memory location that stores a value.
In Go, we declare variables using the following syntax or keywords:
var keyword
:= → using this syntax for short and fast declaration.
varpackage main
import "fmt"
func main() {
var name string = "Rohit Lokhande"
var age int = 25
fmt.Println(name, age)
}
name := "Rohit"
age := 25
:= this will automatically infers the type based on the value.
Note := this declaration can only be used inside functions.
var(
name="Rohit"
age = 25
city = "Pune"
)
Variables declared outside any function are package-level, which are accessible within the package.
package main
import "fmt"
var global = "I am global"
func main() {
local := "I am local"
fmt.Println(global)
fmt.Println(local)
}
Go uses iota to create enumerated constants easily. It is a keyword in Golang that holds an integer value.
It is typically used within constant declarations to generate a series of related values, incrementing by 1 for each subsequent constant.
const (
Sunday = iota
Monday
Tuesday
Wednesday
)
fmt.Println(Sunday, Monday, Tuesday) // 0 1 2
Every new line with a constant increments iota by 1. This is used widely for status codes, enums etc
iota with ExpressionsThis is also used with expressions to define more complex constant values. Let’s understand with an example. If we want to define constants representing file sizes in bytes, kilobytes, megabytes, and so on, we can achieve this in a simple way using iota.
pacakge main
import "fmt"
const (
_ = iota // Discard the first value (0)
KB = 1 << (10 * iota) // 1 << (10 * 1)
MB = 1 << (10 * iota) // 1 << (10 * 2)
GB = 1 << (10 * iota) // 1 << (10 * 4)
)
func main() {
fmt.Println("KB:", KB)
fmt.Println("MB:", MB)
fmt.Println("GB:", GB)
fmt.Println("TB:", TB)
}
In this, we use bitwise left shifts (<<) in conjunction with iota to calculate the constant values for different file sizes.
All variables must be used otherwise Go will throws a compile-time error.
Variables are block-scoped.
You can declare multiple variable together
var x, y = 10,20
Catches mistakes early
If you declare a variable but forget to use it, the compiler will let you know right away, preventing a runtime bug from hiding that mistake.
Encourages clean code
No unused variables mean the code is easier to read and has fewer maintenance issues.
Smaller/safer binaries
Unused imports and values can make builds more complicated or cause unexpected problems. Not allowing them helps keep builds straightforward and predictable.
Example for above rule
Broken- compiler error code
package main
func main() {
var x int // declared but never using
y := 10 // declared but never used
}
Compiler will complain: x declared and not used
Fixed - use the variables
package main
import "fmt"
func main() {
var x int
y := 10
x = y * 2
fmt.Println(x) // now both x and y are used
}
If you we really want to discard a value, we can use the black identifier _ . This tells the compiler “I intentionally don’t need this.“
Ignore a return value:
x, _ := someFunc() // ignore second return value
Mark a value as used (silence unused variable):
var x = someFunc()
_ = x // explicitly mark "x" as used so compiler won't complain
If the compiler says "declared and not used," either remove the declaration or actually use the variable.
While experimenting, _ = x is a quick way to silence errors, but prefer to remove dead code before committing.
For multi-value returns where only some values matter, use _ for the ones you want to drop.
Constant is an immutable value - once defined, it cannot be changed.
Declaring Constants
const PI 3.14
const Greeting = "Hello, Go!"
Constants can also be grouped
const (
StatusOK = 200
StatusNotFound = 404
)
If you try to modify a constant, Go will throw an error:
PI =3.142145 // ❌ compile-time error
| Category | Types | Example |
| Numeric | int, float32,float64,complex64,complex128 | var age int = 5 |
| String | string | var name string = “Rohit” |
| Boolean | bool | var isDev bool = true |
| Derived | array,slice,map,struct,interface | Covered later. |
In this section, we won't dive deep into the differences between float32, float64, and other numeric types. We will discuss non-primitive data types like arrays and slices later.
Go automatically infers type if not specified
count:= 10 // int
price:=99.99 // float64
message:="Hello" // string
Type inference means Go can automatically determine the data type of a variable based on the value you assign to it, so you don’t have to explicitly write the type every time.
Even though Go is statically typed, meaning types are checked at compile time, not runtime, it doesn’t always require you to write them explicitly because the compiler can infer them.
Inference happens only during declaration, not late:
var x int
x = 10.5 // Error - 10.5 is float64, not int
You can’t mix inferred and explicit types in one declaration
var a, b = 1, "hello" // ✅ both inferred
var c, d int = 1, "hi" // ❌ type mismatch for d
Inference doesn’t mean dynamic typing
Once inferred, the type is fixed and checked at compile time.
In Go, uninitialized variables are not garbage they take zero values automatically
| Type | Zero Value |
| int, float | 0 |
| string | ““ |
| bool | false |
| pointer,slice,map | nill |
Go doesn’t support implicit conversions you must convert explicitly
var a int = 10
var b float64 = float64(a)
fmt.Println(b)
Variables, constants, and data types form the foundation of any Go program. Go’s simple but strong type system encourages clean, predictable code, so you always know what’s stored where.
In the next post, we’ll dive into Functions in Go, where you’ll learn how to organize and reuse logic efficiently.