Questions
What is the difference between a struct and an interface in Go?
The Scenario
You are a backend engineer at a fintech company. You are designing a new service that needs to model a variety of different financial instruments, such as stocks, bonds, and options.
You are not sure whether to use a struct or an interface to model the financial instruments.
The Challenge
Explain the difference between a struct and an interface in Go. What are the pros and cons of each approach, and which one would you choose for this use case?
A junior engineer might try to use a struct for everything. They might not be aware of the benefits of using interfaces for abstraction and polymorphism.
A senior engineer would know that a combination of structs and interfaces is the best approach for this use case. They would be able to explain the difference between the two and would have a clear plan for how to use them to model the financial instruments.
Step 1: Understand the Key Differences
| Feature | Struct | Interface |
|---|---|---|
| Purpose | To define a collection of fields. | To define a collection of method signatures. |
| Implementation | Concrete, you create instances of a struct. | Abstract, a type implements an interface by implementing all its methods. |
| Use Cases | When you need to represent a collection of data. | When you need to define a common set of behaviors for different types. |
Step 2: Choose the Right Tool for the Job
For our use case, we should use a combination of structs and interfaces.
- We will use structs to represent the concrete financial instruments, such as
Stock,Bond, andOption. - We will use an interface to define a common set of behaviors for all financial instruments, such as
GetValue().
Step 3: Code Examples
Here’s how we can use a combination of structs and interfaces to model the financial instruments:
package main
import "fmt"
type FinancialInstrument interface {
GetValue() float64
}
type Stock struct {
Ticker string
Price float64
}
func (s Stock) GetValue() float64 {
return s.Price
}
type Bond struct {
Name string
Value float64
}
func (b Bond) GetValue() float64 {
return b.Value
}
func printValue(fi FinancialInstrument) {
fmt.Println(fi.GetValue())
}
func main() {
s := Stock{Ticker: "AAPL", Price: 150.0}
b := Bond{Name: "US Treasury", Value: 1000.0}
printValue(s) // 150
printValue(b) // 1000
}By using a combination of structs and interfaces, we can write code that is flexible, extensible, and easy to maintain.
Practice Question
You want to write a function that can accept any type that has a `String()` method. Which of the following would you use?