ZetCode

Golang type keyword

last modified May 7, 2025

This tutorial explains how to use the type keyword in Go. We'll cover type definitions with practical examples of creating custom types.

The type keyword creates a new named type based on an existing type or defines a new structure. It's fundamental for building type-safe programs.

In Go, type can create type aliases, struct types, interface types, and more. It helps improve code readability and maintainability through strong typing.

Basic type alias

The simplest use of type creates an alias for an existing type. This example demonstrates creating a Celsius type from float64.

basic_type.go
package main

import "fmt"

type Celsius float64

func main() {
    var temp Celsius = 23.5
    fmt.Printf("Temperature: %v°C\n", temp)
    fmt.Printf("Type: %T\n", temp)
}

Celsius is a distinct type from float64 despite sharing the same underlying representation. The %T verb shows the type name.

Struct type definition

type is commonly used to define struct types. This example creates a Person struct with name and age fields.

struct_type.go
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    fmt.Printf("%+v\n", p)
    fmt.Printf("Name: %s, Age: %d\n", p.Name, p.Age)
}

The Person struct groups related data fields. Struct fields are accessed using dot notation. The %+v verb shows field names.

Interface type

Interfaces define method sets that types can implement. This example shows a basic Shape interface with an Area method.

interface_type.go
package main

import (
    "fmt"
    "math"
)

type Shape interface {
    Area() float64
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func main() {
    var s Shape = Circle{Radius: 5}
    fmt.Printf("Area: %.2f\n", s.Area())
}

Circle implements Shape by providing an Area method. The interface variable s can hold any type that satisfies the interface.

Function type

type can define function signatures. This example creates a transformer function type for string manipulation.

func_type.go
package main

import (
    "fmt"
    "strings"
)

type StringTransformer func(string) string

func transform(s string, fn StringTransformer) string {
    return fn(s)
}

func main() {
    upper := func(s string) string {
        return strings.ToUpper(s)
    }
    
    result := transform("hello", upper)
    fmt.Println(result)
}

StringTransformer defines a function type that takes and returns a string. This enables passing functions as arguments while maintaining type safety.

Type embedding

Go supports type embedding for composition. This example embeds a Person type in an Employee type.

embedded_type.go
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

type Employee struct {
    Person
    Position string
    Salary   float64
}

func main() {
    emp := Employee{
        Person:   Person{Name: "Bob", Age: 40},
        Position: "Developer",
        Salary:   75000,
    }
    
    fmt.Printf("%+v\n", emp)
    fmt.Printf("Name: %s, Position: %s\n", emp.Name, emp.Position)
}

Employee embeds Person, inheriting its fields and methods. Embedded fields can be accessed directly without qualification.

Type switch

Type switches work with custom types. This example demonstrates type checking with a switch statement.

type_switch.go
package main

import "fmt"

type ID string
type Number int

func printType(x interface{}) {
    switch v := x.(type) {
    case ID:
        fmt.Printf("ID: %v\n", v)
    case Number:
        fmt.Printf("Number: %v\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
}

func main() {
    printType(ID("abc123"))
    printType(Number(42))
    printType("test")
}

The type switch checks the dynamic type of the interface value. Each case matches a specific type, with default handling unmatched types.

Method receivers

Custom types can have methods. This example adds methods to a Distance type.

method_receiver.go
package main

import "fmt"

type Distance float64

func (d Distance) Meters() float64 {
    return float64(d)
}

func (d Distance) Kilometers() float64 {
    return float64(d) / 1000
}

func main() {
    dist := Distance(1500)
    fmt.Printf("%.2f meters = %.2f kilometers\n",
        dist.Meters(), dist.Kilometers())
}

Methods are defined with receiver parameters before the function name. The Distance type gains Meters and Kilometers methods for unit conversion.

Source

Go language specification

This tutorial covered the type keyword in Go with practical examples of creating custom types, structs, interfaces, and methods.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Golang tutorials.