Real-World Applications
JSON Data Processing
Type switches are particularly useful when parsing complex JSON data with multiple possible types:
func processJSONData(data interface{}) {
switch v := data.(type) {
case map[string]interface{}:
for key, value := range v {
switch typedValue := value.(type) {
case string:
fmt.Printf("String field: %s = %s\n", key, typedValue)
case float64:
fmt.Printf("Numeric field: %s = %f\n", key, typedValue)
case bool:
fmt.Printf("Boolean field: %s = %t\n", key, typedValue)
}
}
case []interface{}:
for i, item := range v {
fmt.Printf("Array item %d: %v\n", i, item)
}
}
}
Error Handling and Logging
func advancedErrorHandling(err error) {
switch e := err.(type) {
case *os.PathError:
fmt.Printf("Path error: %s\n", e.Path)
case *net.OpError:
fmt.Printf("Network operation error: %v\n", e)
case syscall.Errno:
fmt.Printf("System call error: %d\n", e)
default:
fmt.Printf("Unknown error type: %v\n", err)
}
}
Application Architecture Patterns
graph TD
A[Interface Input] --> B{Type Switch}
B --> C[Database Handler]
B --> D[Network Handler]
B --> E[File System Handler]
B --> F[Cache Handler]
Common Use Case Scenarios
Scenario |
Type Switch Application |
API Response Parsing |
Handle multiple response types |
Configuration Management |
Process different config formats |
Plugin Systems |
Dynamic type resolution |
Data Transformation |
Convert between type representations |
Polymorphic Behavior Implementation
type Processor interface {
Process() string
}
type TextProcessor struct {
content string
}
type NumberProcessor struct {
value int
}
func (t *TextProcessor) Process() string {
return strings.ToUpper(t.content)
}
func (n *NumberProcessor) Process() string {
return fmt.Sprintf("Squared: %d", n.value * n.value)
}
func processGeneric(p Processor) {
switch v := p.(type) {
case *TextProcessor:
fmt.Println("Text Processing:", v.Process())
case *NumberProcessor:
fmt.Println("Number Processing:", v.Process())
}
}
func monitorPerformance(metric interface{}) {
switch m := metric.(type) {
case time.Duration:
fmt.Printf("Execution Time: %v\n", m)
case int64:
fmt.Printf("Memory Usage: %d bytes\n", m)
case float64:
fmt.Printf("CPU Utilization: %.2f%%\n", m)
}
}
Best Practices for Real-World Applications
- Use type switches for flexible data handling
- Implement clear, predictable type conversion logic
- Provide comprehensive error handling
- Keep type switch complexity manageable
LabEx Recommendation
Type switches offer powerful runtime type inspection in Go. While versatile, they should be used judiciously to maintain code readability and performance.
By understanding these real-world applications, developers can leverage type switches to create more dynamic and adaptable Go applications across various domains.