Menu
Coddy logo textTech

Type Assertion

Part of the Object Oriented Programming section of Coddy's GO journey — lesson 29 of 107.

A type assertion extracts the concrete type from an interface value. When you have a value stored in an interface (like any), type assertion lets you access the underlying type and its specific methods or fields.

The syntax uses parentheses after the interface value:

var value any = "hello"

str := value.(string)  // Extract the string
fmt.Println(str)       // hello

If the assertion is wrong, your program panics. Asserting value.(int) when it holds a string causes a runtime error. To handle this safely, use the two-value form:

var value any = 42

str, ok := value.(string)
if ok {
    fmt.Println("It's a string:", str)
} else {
    fmt.Println("Not a string")  // This prints
}

The second return value ok is a boolean indicating whether the assertion succeeded. If it fails, ok is false and str receives the zero value of the asserted type.

Type assertions also work with non-empty interfaces. You can assert that an interface value implements another interface or is a specific concrete type:

type Speaker interface {
    Speak() string
}

var s Speaker = Dog{Name: "Buddy"}

dog, ok := s.(Dog)
if ok {
    fmt.Println(dog.Name)  // Access Dog-specific field
}

Always prefer the two-value form in production code to avoid unexpected panics when the underlying type doesn't match your expectation.

challenge icon

Challenge

Easy

Let's build a data inspector that can safely extract and display information from values stored in the empty interface. You'll use type assertions with the two-value form to handle different types without causing panics.

You'll organize your code across two files:

  • inspector.go: Create a function called Inspect that takes a value of type any and returns a descriptive string. Your function should use the two-value form of type assertion to safely check if the value is a string, int, or float64, and return an appropriate message for each type. If the value doesn't match any of these types, return a message indicating an unknown type.
  • main.go: Read values from input, store them in any variables (converting to the appropriate types), then use your Inspect function to analyze each value and print the results.

The following inputs will be provided:

  • Line 1: A string value
  • Line 2: An integer value
  • Line 3: A float value

Your Inspect function should return strings in these formats based on successful type assertions:

  • For strings: String value: [value]
  • For integers: Integer value: [value]
  • For floats: Float value: [value]
  • For unknown types: Unknown type

For example, given hello, 42, and 3.14, your output should be:

String value: hello
Integer value: 42
Float value: 3.14

Remember to use the safe two-value form value, ok := x.(Type) for each assertion. Check the ok boolean before using the extracted value, and try each type in sequence until you find a match or determine the type is unknown.

Cheat sheet

A type assertion extracts the concrete type from an interface value, allowing you to access the underlying type and its specific methods or fields.

Basic syntax:

var value any = "hello"

str := value.(string)  // Extract the string
fmt.Println(str)       // hello

If the assertion is wrong, your program panics. To handle this safely, use the two-value form:

var value any = 42

str, ok := value.(string)
if ok {
    fmt.Println("It's a string:", str)
} else {
    fmt.Println("Not a string")  // This prints
}

The second return value ok is a boolean indicating whether the assertion succeeded. If it fails, ok is false and the first value receives the zero value of the asserted type.

Type assertions work with non-empty interfaces too:

type Speaker interface {
    Speak() string
}

var s Speaker = Dog{Name: "Buddy"}

dog, ok := s.(Dog)
if ok {
    fmt.Println(dog.Name)  // Access Dog-specific field
}

Always prefer the two-value form in production code to avoid unexpected panics.

Try it yourself

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Read the string value
	strVal, _ := reader.ReadString('\n')
	strVal = strings.TrimSpace(strVal)

	// Read the integer value
	intLine, _ := reader.ReadString('\n')
	intLine = strings.TrimSpace(intLine)
	intVal, _ := strconv.Atoi(intLine)

	// Read the float value
	floatLine, _ := reader.ReadString('\n')
	floatLine = strings.TrimSpace(floatLine)
	floatVal, _ := strconv.ParseFloat(floatLine, 64)

	// Store values in any variables
	var val1 any = strVal
	var val2 any = intVal
	var val3 any = floatVal

	// TODO: Use the Inspect function to analyze each value and print the results
	_ = val1
	_ = val2
	_ = val3
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming