Hi there! I'm Maneshwar. Currently, I’m building a private AI code review tool that runs on your LLM key (OpenAI, Gemini, etc.) with flat, no-seat pricing — designed for small teams. Check it out, if that’s your kind of thing.
Go doesn’t have traditional enums like some other languages, but that doesn’t stop us from implementing enum-like behavior.
Combine that with powerful struct
and interface
capabilities, and you get clean, maintainable, type-safe code.
Let’s break it down with minimal theory and direct usage.
Enum in Go (aka Typed Constants)
Go doesn’t have a native enum
keyword, but you can get enum-like behavior using const
+ iota
.
type Status int
const (
Pending Status = iota
Processing
Completed
Failed
)
func (s Status) String() string {
return [...]string{"Pending", "Processing", "Completed", "Failed"}[s]
}
Why use this?
- Type safety.
- Can attach methods (like
.String()
). - Cleaner switch-case usage.
func HandleStatus(s Status) {
switch s {
case Pending:
fmt.Println("Pending...")
case Completed:
fmt.Println("Done.")
default:
fmt.Println("Unknown status.")
}
}
Struct in Go
struct
is your bread and butter in Go — a collection of fields. Think of it like a lightweight class without inheritance.
type User struct {
ID int
Name string
Email string
}
You can attach methods:
func (u User) IsEmailVerified() bool {
return strings.HasSuffix(u.Email, "@verified.com")
}
Structs are passed by value unless you use a pointer (*User
).
Interface in Go
Interfaces in Go are satisfied implicitly. If a type implements the method(s), it satisfies the interface — no need to declare it.
type Notifier interface {
Notify(message string)
}
Implement it:
type EmailNotifier struct {
Email string
}
func (e EmailNotifier) Notify(msg string) {
fmt.Printf("Sending email to %s: %s\n", e.Email, msg)
}
Use it:
func SendAlert(n Notifier) {
n.Notify("Server down")
}
Putting It Together
Here’s how all 3 concepts come together.
type AlertLevel int
const (
Info AlertLevel = iota
Warning
Critical
)
type Alert struct {
Level AlertLevel
Message string
}
type Notifier interface {
Notify(message string)
}
type SlackNotifier struct {
Channel string
}
func (s SlackNotifier) Notify(msg string) {
fmt.Printf("Sending Slack message to %s: %s\n", s.Channel, msg)
}
func SendAlert(n Notifier, a Alert) {
n.Notify(fmt.Sprintf("[%s] %s", a.Level.String(), a.Message))
}
func (a AlertLevel) String() string {
return [...]string{"INFO", "WARNING", "CRITICAL"}[a]
}
Usage
func main() {
slack := SlackNotifier{Channel: "#ops"}
alert := Alert{
Level: Critical,
Message: "Database connection lost",
}
SendAlert(slack, alert)
}
Final Thoughts
- Use
const
+iota
for enums. - Use
struct
to group data and behavior. - Use
interface
for decoupled, flexible code.
That’s it. No magic — just Go’s simple but powerful type system.
LiveReview helps you get great feedback on your PR/MR in a few minutes.
Saves hours on every PR by giving fast, automated first-pass reviews. Helps both junior/senior engineers to go faster.
If you're tired of waiting for your peer to review your code or are not confident that they'll provide valid feedback, here's LiveReview for you.
Top comments (0)