Go by Example: Type Inference
Go compiler can deduce the type of a variable from its initialization value. This example demonstrates type inference with `var` and the short declaration operator `:=`, and explains when to use each.
Code
package main
import "fmt"
func main() {
// 1. Using 'var' with type inference
// The compiler infers the type from the value on the right.
var name = "Gopher" // inferred as string
var age = 10 // inferred as int
var active = true // inferred as bool
fmt.Printf("name: %T, age: %T, active: %T\n", name, age, active)
// 2. Short declaration operator ':='
// This is the most common way to declare local variables.
// It works exactly like 'var' with inference but is more concise.
city := "Jakarta"
population := 10_000_000
fmt.Printf("city: %T, population: %T\n", city, population)
// 3. Inference with function return values
// You rarely need to specify types when capturing return values.
res, err := someFunction()
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", res)
// 4. Floating point inference
// Numbers with decimals are inferred as float64 by default.
pi := 3.14159
fmt.Printf("pi is type: %T\n", pi)
}
func someFunction() (int, error) {
return 42, nil
}
Explanation
Type inference allows the Go compiler to automatically determine the type of a variable based on the value you assign to it. This means you don't always have to explicitly write int, string, or bool. This feature makes Go code concise like a dynamic language (Python, JavaScript) while maintaining the safety and performance of a statically typed language.
There are two main ways to use inference:
1. var name = value: Used when you want to declare a variable without a specific type but with an initial value.
2. name := value: The "short declaration" syntax. This is the preferred method for local variables inside functions. It declares and initializes the variable in one step.
Note that inference always chooses the "default" type for untyped constants: int for integers, float64 for floating-point numbers, and complex128 for complex numbers.
- Conciseness: Reduces boilerplate code.
- Safety: Variables are still statically typed; you can't change the type later.
- Scope:
:=can only be used inside functions. - Defaults:
3.14becomesfloat64, notfloat32.

