Go type assertion

In Go, type assertion is a mechanism for checking the actual type of an interface value.

Type assertion is an important tool in Go for handling interface types; it allows us to extract a concrete type from an interface value and operate on it.

Type assertion is often used to handle variables of interface type, because an interface variable can store any value of a concrete type that implements that interface.

Basic Syntax

The basic syntax for type assertions is as follows:

value, ok := interfaceValue.(Type)
  • interfaceValueis a variable of an interface type.
  • Typeis the type you want to assert.
  • valueis the value of the specific type after the assertion succeeds.
  • okIt is a boolean value indicating whether the assertion succeeded.

If the assertion succeeds,valuewill beinterfaceValuethe actual value,okistrue; if the assertion fails,valuewill beTypethe zero value,okisfalse。

Example

package main

import "fmt"

func main() {
    var i interface{} = "Hello, Go!"

    // Try to assert i as string type
    s, ok := i.(string)
    if ok {
        fmt.Println("Assertion succeeded:", s)
    } else {
        fmt.Println("Assertion failed")
    }

    // Try to assert i as int type
    n, ok := i.(int)
    if ok {
        fmt.Println("Assertion succeeded:", n)
    } else {
        fmt.Println("Assertion failed")
    }
}

Output result

断言成功: Hello, Go!
断言失败

Another form of type assertion

In addition to the above,value, ok := interfaceValue.(Type)In addition to that form, Go also supports another form of type assertion that does not return a boolean value, but instead raises a panic directly when the assertion fails.

The syntax for this form is as follows:

value := interfaceValue.(Type)

Example code

Example

package main

import "fmt"

func main() {
    var i interface{} = "Hello, Go!"

    // Directly assert as string type
    s := i.(string)
    fmt.Println("Assertion succeeded:", s)

    // Directly assert as int type (will cause panic)
    n := i.(int)
    fmt.Println("Assertion succeeded:", n)
}

Output result

断言成功: Hello, Go!
panic: interface conversion: interface {} is string, not int

Common uses of type assertions

1. Handling interface values with multiple types

Go also provides a specialtype switchsyntax to test multiple types:

switch v := i.(type) {
case T1:
    // v的类型是T1
case T2:
    // v的类型是T2
default:
    // 默认情况
}

When an interface variable may store values of multiple types, type assertions can help us perform different operations based on the actual type.

Example

func printType(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Println("This is an integer:", v)
    case string:
        fmt.Println("This is a string:", v)
    default:
        fmt.Println("unknown type")
    }
}

2. Extracting a concrete type from an interface

When dealing with variables of interface type, we may need to convert them to a concrete type for further operations.

Example

func processInterface(i interface{}) {
    if s, ok := i.(string); ok {
        fmt.Println("Processing string:", s)
    } else if n, ok := i.(int); ok {
        fmt.Println("Processing integer:", n)
    } else {
        fmt.Println("Unhandled type")
    }
}

Notes

  1. Type assertions can only be used on interface typesNote: type assertion can only be used on variables of interface type, not on variables of non-interface type.
  2. Avoid panicNote: when using a type assertion that does not return a boolean value, make sure the assertion will not fail, otherwise it will cause a panic.
  3. Performance of type assertions: Type assertions perform type checks at runtime, which may incur some performance overhead. They should be used with caution in performance-sensitive scenarios.
other extensions