Lesson 4/41 · Go Language Intro & Dev Environment Beginner m01-l04

Go Basics: Variables, Constants, Primitive Types and Type Conversion

Module 1: Go Language Intro & Dev Environment | Lesson: m01-l04 | Level: Beginner After this lesson you will be able to: declare variables and constants the Go way, understand the zero-value mechanism and the type system, and correctly use the standard library for type conversion.

Learning Objectives

  • Use var and := to declare variables correctly, and understand the difference between multi-variable assignment and parallel assignment.
  • Explain the zero-value mechanism and list the zero values of int, string, bool, float64 and the reference types.
  • Use const and iota to define enumeration constants, and understand the implicit conversion rules of untyped constants.
  • Use the strconv package to convert explicitly between strings and numbers.

Core Concepts

2.1 Variable Declaration: var and :=

In Go, a variable is a container that stores data. Go offers two main ways to declare variables: the var keyword and the short variable declaration :=.

1. What - var declaration: explicitly declares the variable's type. The syntax is var name type = value. If you omit value, the variable is given the zero value of its type. - := short declaration: infers the type implicitly. The syntax is name := value. It can only be used inside a function, and the left-hand side must contain at least one new variable.

2. Why it is designed this way Go emphasizes explicitness and simplicity. var suits package-level variables or cases where you want an explicit type; := suits local variables, cutting down boilerplate and improving readability.

3. How

// Explicit declaration
var age int = 18
var name string = "Alice"

// Implicit declaration (short variable)
count := 10
isActive := true

// Multi-variable declaration
var x, y int = 1, 2
a, b := 3, 4

2.2 The Zero-Value Mechanism

In Go, a variable that is declared without explicit initialization automatically receives the type's zero value. This avoids undefined behavior and is a manifestation of Go's safety.

Type Zero value
int, int8, int16, int32, int64 0
float32, float64 0.0
bool false
string "" (empty string)
pointers, slices, maps, channels, functions, interfaces nil

2.3 Constants and iota

Constants are fixed at compile time and cannot be modified at runtime.

1. iota enumeration iota is a predeclared identifier that starts at 0 in a const block and increments by 1 on each line. - Note: iota only works inside const blocks; it cannot be used in a var block. - Rule: inside each const block, iota starts at 0 and increments by 1 per constant specification; a new const block starts again at 0, and you can skip a line with _.

2. Untyped constants Go supports untyped constants, such as 3.14 or 100. They have no concrete type until they are assigned to a variable or used in a context that demands a type, at which point their type is determined by context. This lets constants convert implicitly to compatible types.

2.4 Primitive Types and Type Conversion

Go is a strongly typed language and forbids implicit type conversion. Conversions between different primitive types must be explicit.

1. Primitive types - Integers: int, int8, int16, int32, int64, uint, uint8 (alias byte), uint16, uint32, uint64 - Floating point: float32, float64 - Complex: complex64, complex128 - Characters: byte (alias of uint8), rune (alias of int32) - Boolean: bool - String: string

2. Explicit type conversion The syntax is T(v), where T is the target type and v is an expression. - Numeric conversion: int(f) truncates a floating-point number to an integer. - String conversion: use the strconv package. For example, strconv.Atoi(string) converts a string to int, and strconv.Itoa(int) converts an integer to a string.

Important rule: constant truncation When an untyped constant is converted to a typed variable, the compiler reports an error if precision would be lost (such as float to integer). For example, int(3.14) is illegal: 3.14 is an untyped floating-point constant, and converting it directly to int loses precision. You must first assign it to a typed variable and then convert: var f float64 = 3.14; var i int = int(f).

Example Code

Example 1: Variable Declaration, Zero Values and iota Enumeration

This example shows the difference between var and :=, demonstrates the zero-value mechanism, and uses iota to define color constants.

package main

import "fmt"

// A package-level variable declared with var; its zero value is 0.
var globalCounter int

func main() {
    // 1. Variable declaration
    var name string // zero value is ""
    var age int = 18
    localVar := "Hello" // short declaration, type inferred as string

    fmt.Printf("Name: %q, Age: %d, LocalVar: %s\n", name, age, localVar)
    fmt.Printf("Global Counter (zero value): %d\n", globalCounter)

    // 2. iota enumeration
    type Color uint8
    const (
        Red   Color = iota // 0
        Green              // 1
        Blue               // 2
    )

    fmt.Printf("Red: %d, Green: %d, Blue: %d\n", Red, Green, Blue)
}

Expected output:

Name: "", Age: 18, LocalVar: Hello
Global Counter (zero value): 0
Red: 0, Green: 1, Blue: 2

Example 2: Type Conversion and Using strconv

This example demonstrates explicit numeric conversion, the limits on constant conversion, and converting between strings and integers with strconv.

package main

import (
    "fmt"
    "strconv"
)

func main() {
    // 1. Explicit numeric conversion
    var f float64 = 3.14
    // Note: you cannot write var i int = int(3.14) directly,
    // because the untyped constant 3.14 cannot be converted to int directly.
    // It must first be assigned to a typed variable and then converted.
    var i int = int(f)
    fmt.Printf("Float: %f -> Int: %d\n", f, i)

    // 2. Converting between string and integer
    strNum := "123"
    num, err := strconv.Atoi(strNum)
    if err != nil {
        fmt.Printf("Error converting %s to int: %v\n", strNum, err)
        return
    }
    num++
    backToStr := strconv.Itoa(num)
    fmt.Printf("String: %s -> Int: %d -> String: %s\n", strNum, num, backToStr)

    // 3. A bad conversion example (commented out, otherwise compilation fails)
    // var badInt int = int(3.14) // compile error: cannot convert 3.14 (untyped float constant) to type int
}

Expected output:

Float: 3.140000 -> Int: 3
String: 123 -> Int: 124 -> String: 124

Common Mistakes & Pitfalls

  1. Wrong assumption: believing var i int = 3.14 is legal because Go allows implicit conversion.

    • Why: Go forbids implicit conversion between typed values. 3.14 is an untyped floating-point constant, but when it is assigned to an int variable, the compiler checks for precision loss and reports cannot use 3.14 (untyped float constant) as int value in variable declaration (truncated). Only untyped constants convert implicitly between compatible types (e.g. var f float64 = 1).
    • Correct approach: convert explicitly: var f float64 = 3.14; var i int = int(f).
  2. Wrong assumption: using iota inside a var block.

    • Why: iota is an enumeration counter specific to const blocks. It is not supported in var blocks; writing var ( A = iota ) causes the syntax error syntax error: unexpected newline, expected type.
    • Correct approach: use iota only in const blocks. Group package-level variables with var (...), but do not use iota inside.
  3. Wrong assumption: using int(3.14) directly as a constant conversion.

    • Why: the untyped constant 3.14 cannot be converted directly to int because it loses the fractional part. The compiler reports cannot convert 3.14 (untyped float constant) to type int.
    • Correct approach: first assign it to a typed variable and then convert: var f float64 = 3.14; var i int = int(f).

Best Practices

  1. Prefer := for local variables: inside a function, := makes the code more concise, and type inference is usually accurate. Use var only when you need an explicit type or are declaring package-level variables.
  2. Leverage zero values to simplify initialization: do not explicitly initialize variables to 0 or "" unless it carries specific meaning. Go's zero values are usually safe defaults.
  3. Use iota for enumeration constants: when you need a group of related constants (such as status codes, colors, error codes), use a const block with iota to avoid magic numbers.
  4. Convert types explicitly: always use T(v) for type conversion; do not rely on implicit conversion (which barely exists in Go). For numeric conversions, watch out for truncation.
  5. Use strconv for string conversion: do not hand-parse strings; use the standard strconv package, which is optimized and handles edge cases.

Exercises

  1. Concept question: explain the zero-value mechanism, give the zero values of int, string, bool and float64, and list which types (pointer/slice/map/channel/function/interface) have nil as their zero value.
  2. Coding exercise: write a function convertAndPrint that takes a float64 argument, converts it to int, then uses strconv.Itoa to turn the result into a string, and finally prints that string.
  3. Advanced/debugging exercise: the code below tries to convert a floating-point constant directly to an integer. Find the error and fix it. ```go package main

    import "fmt"

    func main() { var discount int = int(3.14) fmt.Printf("Discount: %d\n", discount) } ```

Reference Answers

Reference Answers (click to expand / collapse)

Question 1

Answer: The zero value is the default value a Go variable takes when it is not explicitly initialized. - The zero value of int is 0. - The zero value of string is "" (the empty string). - The zero value of bool is false. - The zero value of float64 is 0.0. - The zero value of pointers, slices, maps, channels, functions and interfaces is nil.

Question 2

package main

import (
    "fmt"
    "strconv"
)

func convertAndPrint(f float64) {
    // Explicitly convert to int, truncating the fractional part
    i := int(f)
    // Convert the int to a string
    s := strconv.Itoa(i)
    fmt.Println(s)
}

func main() {
    convertAndPrint(3.14) // prints: 3
}

Explanation: the function takes a float64, converts and truncates it explicitly with int(f), then turns it into a string with strconv.Itoa and prints it.

Question 3

The problem: The line var discount int = int(3.14) is a compile error. The reason is that the untyped constant 3.14 cannot be converted directly to type int because it loses precision (truncation). The Go compiler does not allow this kind of implicit precision-losing conversion.

Fixed code:

package main

import "fmt"

func main() {
    // The correct approach: assign to a typed variable first, then convert
    var f float64 = 3.14
    var discount int = int(f)
    fmt.Printf("Discount: %d\n", discount)
}

Lesson Summary

  • Go offers two ways to declare variables, var and :=; := is more concise but works only inside functions.
  • Every variable has a well-defined zero value, and the zero value of reference types (pointers, slices, etc.) is nil.
  • iota is an enumeration counter in const blocks, starting at 0 and incrementing; it applies only to constants.
  • Go forbids implicit type conversion; you must use T(v) explicitly, and constant conversion must not lose precision.
  • The strconv package is the standard tool for converting between strings and numbers.

Next lesson preview: operators, control flow and variable scope — Go's idiomatic if, for and switch.

Feedback

This site is front-end only — no backend, no accounts — so feedback goes to GitHub Issues, Discussions, or email.

Paste it into the issue or email to help track it down — it never includes anything you typed

Also:Browse existing issues · Email feedback (no GitHub account needed):278975598@qq.com