Go Type Casting: Conversions, Assertions, and Interface to Struct

Golang cast and go cast usually mean explicit type conversion (numeric) or type assertion from any: golang type casting vs strconv for strings, safe v.(T) and golang cast interface to struct with value or pointer types.

Published

Updated

Read time 4 min read

Reviewed byDeepak Prasad

Go Type Casting: Conversions, Assertions, and Interface to Struct

If you are looking up golang cast, go cast, golang casting, go casting, or golang type casting, the Go spec still names two separate mechanisms: conversions for compatible static types, and type assertions for values stored in any (formerly spelled interface{}). Go type casting in the C sense—silent widening or narrowing—does not exist; you write float64(i), use strconv between strings and numbers, and use v.(T) or a type switch when a value started life inside an interface. For more on assertions alone, see type assertion in Go.

Tested with Go 1.24 on Linux.


Conversions vs assertions (the two “casts”)

A conversion reinterprets a value as another type the compiler allows, for example float64(i) or int(f) (fractional part is truncated toward zero). An assertion asks an interface value what concrete type it holds: v.(string) or v, ok := x.(MyType). Mixing them up is the main source of confusion when reading casting golang tutorials.

Idea Typical syntax When it runs If it fails
Conversion float64(x), uint16(n) Compile-time check Compile error
Assertion x.(T), x.(type) in switch Runtime Panic or ok == false

Numeric and string conversions

Use conversions between numeric types when the spec allows it. For golang type cast between strings and numbers, use strconv—there is no int("123") conversion.

go
package main

import (
	"fmt"
	"strconv"
)

func main() {
	i := 10
	fmt.Println(float64(i))

	f := 10.9
	fmt.Println(int(f))

	s := "123"
	n, err := strconv.Atoi(s)
	if err != nil {
		panic(err)
	}
	fmt.Println(strconv.Itoa(n), n)

	x, err := strconv.ParseFloat("3.14", 64)
	if err != nil {
		panic(err)
	}
	fmt.Println(x)
}
Output

Run locally: you should see 10, 10, 123 123, and 3.14.


Type assertions and any (interface “casting”)

Dynamic APIs (JSON decoders, database/sql rows) often hand you an any (interface{}). Go casting in that situation means a type assertion or type switch, not MyType(x).

Safe assertion with ok

go
package main

import "fmt"

func main() {
	var val any = "hello"
	str, ok := val.(string)
	if ok {
		fmt.Println(str)
	}
	_, ok = val.(int)
	if !ok {
		fmt.Println("not an int")
	}
}
Output

You should see hello then not an int.

Type switch

go
package main

import "fmt"

func describe(v any) {
	switch t := v.(type) {
	case int:
		fmt.Println("int", t)
	case string:
		fmt.Println("string", t)
	default:
		fmt.Println("other")
	}
}

func main() {
	describe(42)
	describe("x")
}
Output

You should see int 42 then string x.

Golang cast interface to struct (value and pointer)

Assert to the same kind you stored: value struct .(User) versus pointer .(*User).

go
package main

import "fmt"

type User struct {
	Name string
}

func main() {
	var v any = User{Name: "Ada"}
	if u, ok := v.(User); ok {
		fmt.Println("value", u.Name)
	}

	var p any = &User{Name: "Bob"}
	if u2, ok := p.(*User); ok {
		fmt.Println("pointer", u2.Name)
	}
}
Output

You should see value Ada and pointer Bob.


Common mistakes

Single-value assertion with the wrong type panics:

go
var val any = "hello"
// num := val.(int) // panic — do not use without ok

String to int is not a conversion:

go
// var s string = "123"
// i := int(s) // compile error

Use strconv.Atoi and handle errors.


Summary

Golang cast and go cast usually refer to one of three things: explicit numeric conversion with T(x), string and number parsing with strconv, or type assertion from any with v.(T) and the comma-ok form. Regardless of phrasing, golang type casting is not implicit: the compiler rejects unsafe conversions, and interface assertions need ok or a type switch unless the dynamic type is guaranteed. For golang cast interface to struct, assert to the struct or pointer type that was actually stored, and prefer a type switch when many shapes are possible.


References


Frequently Asked Questions

1. What do people mean by golang cast or go cast?

Colloquially it is either an explicit conversion such as float64(i) or a type assertion such as v.(string) on an interface value; the spec uses conversion and type assertion, not the word cast.

2. What is the difference between golang type casting and type assertion?

Type conversion applies to compatible static types at compile time; type assertion extracts a concrete type from an interface value at runtime and can panic without the comma-ok form.

3. How do I golang cast interface to struct?

Use a type assertion to the struct type or *Struct: s, ok := v.(MyStruct) or ps, ok := v.(*MyStruct); use a type switch when several concrete types are possible.

4. How do I convert string to int in Go?

Use strconv.Atoi or strconv.ParseInt and always handle the error; int(s) does not compile when s is a string.

5. Why does interface conversion panic in Go?

A single-value assertion x.(T) panics when the dynamic type of x is not T; use v, ok := x.(T) or a type switch for control flow instead.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …