DEV Community

Cover image for Understanding Interface in Go
Ganesh Kumar
Ganesh Kumar

Posted on

Understanding Interface in Go

#go

Hello, I'm Ganesh Kumar. I'm working on git-lrc: a Git hook for Checking AI generated code.AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

In my previous post, I explained how methods works.

In this article we will understand how to work with interface.

What is an interface?

An interface is a type that defines a set of methods. It is used to define a contract for a type. It is an abstract signature of a type where we define the methods but not the implementation.


package main

import "fmt"

type shape interface {
    area() float64
}

type rectangle struct {
    width, height float64
}

func (r rectangle) area() float64 {
    return r.width * r.height
}

func main() {
    rect := rectangle{width: 10, height: 20}
    fmt.Println(rect.area())
}
Enter fullscreen mode Exit fullscreen mode

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
200
Enter fullscreen mode Exit fullscreen mode

Interface are container which contains two properties.

  1. Dynamic Type
  2. Dynamic Value

Dynamic Type and Dynamic Value

Dynamic type is the type of the value stored in the interface.

package main

import "fmt"

func main() {
    // 'i' is an empty interface. Currently, both its dynamic type and value are nil.
    var i any 
    fmt.Printf("Value: %v \t Type: %T\n", i, i)

    // Now we assign an integer to it.
    // Dynamic Type becomes 'int', Dynamic Value becomes '42'
    i = 42
    fmt.Printf("Value: %v \t Type: %T\n", i, i)

    // Now we assign a string to it.
    // Dynamic Type becomes 'string', Dynamic Value becomes "Hello"
    i = "Hello"
    fmt.Printf("Value: %v \t Type: %T\n", i, i)

    // Now we assign a float to it.
    // Dynamic Type becomes 'float64', Dynamic Value becomes 3.14
    i = 3.14
    fmt.Printf("Value: %v \t Type: %T\n", i, i)
}
Enter fullscreen mode Exit fullscreen mode

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
Value: <nil>     Type: <nil>
Value: 42        Type: int
Value: Hello     Type: string
Value: 3.14      Type: float64
Enter fullscreen mode Exit fullscreen mode

We can see that the dynamic type and dynamic value changes based on the value assigned to the interface.

Dynamic Type and Dynamic Value using reflection

This is another way to get the dynamic type and dynamic value.

package main

import (
    "fmt"
    "reflect"
)

// A custom struct
type User struct {
    Name string
}

func main() {
    var data interface{} = User{Name: "Alice"}

    // Extracting the dynamic type
    dynamicType := reflect.TypeOf(data)

    // Extracting the dynamic value
    dynamicValue := reflect.ValueOf(data)

    fmt.Println("Reflect Type:", dynamicType)         // main.User
    fmt.Println("Reflect Value:", dynamicValue)       // {Alice}

    // You can even check the underlying "Kind" (e.g., struct, int, ptr)
    fmt.Println("Kind of Type:", dynamicType.Kind())  // struct
}
Enter fullscreen mode Exit fullscreen mode

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
Reflect Type: main.User
Reflect Value: {Alice}
Kind of Type: struct
Enter fullscreen mode Exit fullscreen mode

This way we can get the dynamic type and dynamic value using reflection.

Type Assertion

Type assertion is used to extract the dynamic value from the interface.

This is the basic way to use type assertion.

We try to extract the dynamic value from the interface. As, go is a static typed language, it will throw an error if the dynamic type is not the same as the type we are trying to extract.

package main

import "fmt"

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

    s := i.(string)
    fmt.Println(s)

    s, ok := i.(string)
    fmt.Println(s, ok)

    f, ok := i.(float64)
    fmt.Println(f, ok)

    f = i.(float64)
    fmt.Println(f)
}
Enter fullscreen mode Exit fullscreen mode

If we try to extract the dynamic value from the interface with a different type, it will throw an error.

To avoid this we first check if the dynamic type is the same as the type we are trying to extract.

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
Hello
Hello true
0 false
panic: interface conversion: interface {} is string, not float64
Enter fullscreen mode Exit fullscreen mode

Usage of Type Switch

Based on the dynamic type, we can extract the dynamic value from the interface.

package main

import "fmt"

func printTypeAndValue(i interface{}) {
    fmt.Printf("Type: %T\tValue: %v\n", i, i)
    switch i.(type) {
    case int:
        fmt.Printf("it is int %v\n", i)
    case string:
        fmt.Printf("it is string %v\n", i)
    case bool:
        fmt.Printf("it is bool %v\n", i)
    default:
        fmt.Printf("unknown")
    }
}

func main() {
    // 'i' is an empty interface. Currently, both its dynamic type and value are nil.
    printTypeAndValue("Hello")
    printTypeAndValue(42)
    printTypeAndValue(true)
}
Enter fullscreen mode Exit fullscreen mode

Now we can see that based on the dynamic type, we can extract the dynamic value from the interface. We can print the value base on the dynamic type.

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
Type: string    Value: Hello
it is string Hello
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article we understood how interface works. We also understood how to use type assertion and type switch.

git-lrc

πŸ‘‰ Check out: git-lrc
Any feedback or contributors are welcome! It’s online, open-source, and ready for anyone to use.
⭐ Star it on GitHub:

GitHub logo HexmosTech / git-lrc

Free, Unlimited AI Code Reviews That Run on Commit

git-lrc logo

git-lrc

Free, Unlimited AI Code Reviews That Run on Commit


git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

See It In Action

See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements

git-lrc-intro-60s.mp4

Why

  • πŸ€– AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
  • πŸ” Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
  • πŸ” Build a habit, ship better code. Regular review β†’ fewer bugs β†’ more robust code β†’ better results in your team.
  • πŸ”— Why git? Git is universal. Every editor, every IDE, every AI…




Top comments (0)