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())
}
Output:
gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go
200
Interface are container which contains two properties.
- Dynamic Type
- 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)
}
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
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
}
Output:
gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go
Reflect Type: main.User
Reflect Value: {Alice}
Kind of Type: struct
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)
}
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
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)
}
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
Conclusion
In this article we understood how interface works. We also understood how to use type assertion and type switch.
π 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:
HexmosTech
/
git-lrc
Free, Unlimited AI Code Reviews That Run on Commit
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)