Understanding Variables and Data Types in Go
Variables are fundamental building blocks in Go programming. This guide covers everything you need to know about declaring, initializing, and working with variables in Go.
Variable Declaration
Go provides several ways to declare variables:
1. Basic Declaration
var name string // Declares a string variable
var age int // Declares an integer variable
var isActive bool // Declares a boolean variable
2. Declaration with Initialization
var name string = "Go" // Declare and initialize
var age = 42 // Type inferred from value
var isActive = true // Boolean type inferred
3. Short Declaration
name := "Go" // Declare and initialize
age := 42 // Type inferred
isActive := true // Most common in function bodies
4. Multiple Declarations
var (
name string = "Go"
age int = 42
isActive bool = true
)
// Short declaration
name, age := "Go", 42
Basic Types
Go has several basic types:
1. Numeric Types
// Integers
var (
a int = 42 // Platform dependent (32 or 64 bit)
b int8 = 127 // -128 to 127
c int16 = 32767 // -32768 to 32767
d int32 = 2147483647
e int64 = 9223372036854775807
)
// Unsigned integers
var (
f uint = 42 // Platform dependent
g uint8 = 255 // 0 to 255
h uint16 = 65535 // 0 to 65535
i uint32 = 4294967295
j uint64 = 18446744073709551615
)
// Floating point
var (
k float32 = 3.14 // Single precision
l float64 = 3.14159265359 // Double precision
)
// Complex numbers
var (
m complex64 = 1 + 2i
n complex128 = 1.1 + 2.2i
)
2. String Type
var (
name = "Go"
multiLine = `This is a
multi-line
string`
)
// String operations
length := len(name)
char := name[0] // Get byte at index
slice := name[0:2] // Substring
3. Boolean Type
var (
isTrue = true
isFalse = false
)
// Boolean operations
result := isTrue && isFalse // Logical AND
result = isTrue || isFalse // Logical OR
result = !isTrue // Logical NOT
Zero Values
Variables declared without initialization get zero values:
var (
intZero int // 0
floatZero float64 // 0.0
boolZero bool // false
stringZero string // ""
pointerZero *int // nil
)
Type Conversion
Go requires explicit type conversion:
var (
i int = 42
f float64 = float64(i) // int to float64
u uint = uint(f) // float64 to uint
)
// String conversions
import "strconv"
s1 := strconv.Itoa(i) // Int to string
s2 := strconv.FormatFloat(f, 'f', 2, 64) // Float to string
i2, err := strconv.Atoi("42") // String to int
f2, err := strconv.ParseFloat("3.14", 64) // String to float
Constants
Constants are declared using the const
keyword:
const (
Pi = 3.14159
StatusOK = 200
MaxUsers = 1000
ServerName = "go-server"
)
// iota for enumerated constants
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
Variable Scope
1. Package Level
package main
var globalVar = "I'm global" // Package level
func main() {
println(globalVar) // Accessible
}
func other() {
println(globalVar) // Also accessible
}
2. Function Level
func main() {
localVar := "I'm local" // Function level
if true {
blockVar := "I'm in a block" // Block level
println(localVar) // Accessible
println(blockVar) // Accessible
}
println(localVar) // Accessible
// println(blockVar) // Not accessible (out of scope)
}
Best Practices
1. Variable Naming
// Good names
var (
userID string
firstName string
isValid bool
maxRetries int
)
// Avoid
var (
u string // Too short
firstName1 string // Numbered variables
data string // Too vague
)
2. Short vs. Regular Declaration
// Use var for package level
var maxConnections = 100
func main() {
// Use := for local variables
count := 0
// Use var when zero value is desired
var buffer []byte
// Use var for clarity with types
var client *http.Client
}
3. Grouped Declarations
// Group related variables
var (
// Server configuration
host = "localhost"
port = 8080
// Database configuration
dbUser = "admin"
dbPass = "secret"
)
Common Patterns
1. Error Checking
if value, err := strconv.Atoi("42"); err != nil {
// Handle error
log.Printf("conversion failed: %v", err)
} else {
// Use value
fmt.Printf("converted value: %d", value)
}
2. Multiple Return Values
func divide(x, y float64) (float64, error) {
if y == 0 {
return 0, fmt.Errorf("division by zero")
}
return x / y, nil
}
result, err := divide(10, 2)
3. Blank Identifier
// Ignore unwanted values
_, err := someFunction()
// Import for side effects
import _ "github.com/lib/pq"
Common Mistakes
1. Shadowing Variables
var err error = errors.New("initial error")
func main() {
// Wrong: shadows package level err
if err := someFunction(); err != nil {
log.Fatal(err) // Only sees local err
}
// Right: use different name or existing variable
if err2 := someFunction(); err2 != nil {
log.Fatal(err2)
}
}
2. Unused Variables
func main() {
// Compile error: unused variable
x := 42
// Fix: use the variable or remove it
x := 42
fmt.Println(x)
}
Next Steps
- Learn about control structures
- Explore functions
- Study error handling
- Practice with data types