How to check if value implements interface

Use a type assertion or a type switch to check if a value implements an interface at runtime.

Use a type assertion or a type switch to check if a value implements an interface at runtime. If you need to know the result without panicking, use the two-value form of a type assertion; if you need to handle multiple possible types, a type switch is cleaner.

Here is the two-value type assertion pattern, which is the standard way to check for a specific interface without causing a panic:

func checkInterface(v any) {
    // Check if v implements fmt.Stringer
    if s, ok := v.(fmt.Stringer); ok {
        fmt.Println("Implements Stringer:", s.String())
    } else {
        fmt.Println("Does not implement Stringer")
    }
}

If you need to distinguish between several interfaces or concrete types, a type switch is more idiomatic and readable:

func processValue(v any) {
    switch val := v.(type) {
    case fmt.Stringer:
        fmt.Println("Stringer:", val.String())
    case io.Reader:
        fmt.Println("Reader detected")
    case int:
        fmt.Println("Integer:", val)
    default:
        fmt.Println("Unknown type")
    }
}

For static analysis (compile-time checks), you can use the interface{} type in a function signature or assign the value to a variable of the interface type. If the type doesn't implement the interface, the code will fail to compile, which is often preferable to runtime checks.

// Compile-time check: this will error if MyType doesn't implement fmt.Stringer
func requireStringer(s fmt.Stringer) {
    fmt.Println(s.String())
}

// Usage:
// requireStringer(myValue) // Fails to compile if myValue lacks String() method

Note that checking if a value implements an interface is a runtime operation unless you rely on the compiler to enforce it. The two-value assertion (val, ok := v.(T)) is safe and returns false if the type doesn't match, whereas the single-value form (val := v.(T)) will panic if the assertion fails. Always prefer the two-value form when the type is uncertain.