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.
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)
}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
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")
}
}You should see hello then not an int.
Type switch
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")
}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).
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)
}
}You should see value Ada and pointer Bob.
Common mistakes
Single-value assertion with the wrong type panics:
var val any = "hello"
// num := val.(int) // panic — do not use without okString to int is not a conversion:
// var s string = "123"
// i := int(s) // compile errorUse 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
- The Go Programming Language Specification: Conversions
- The Go Programming Language Specification: Type assertions
- Package strconv
- A Tour of Go: type assertions

