Рассмотрим пример, приведенный ниже, он принимает сообщение JSON, которое в конечном итоге разбивается на несколько возможных типов. Как я могу уменьшить или удалить шаблон кода, связанный с добавлением другого типа события.
package main
import (
"encoding/json"
"fmt"
)
const input = `
{
"type": "hello",
"event": {
"name": "Picard"
}
}
`
type EventEnvelope struct {
Type string
Event interface{}
}
type EventHello struct {
Name string
}
type EventHowdy struct {
Name string
}
type Display struct {
formal chan EventHello
western chan EventHowdy
}
func newDisplay() *Display {
return &Display{
formal: make(chan EventHello),
western: make(chan EventHowdy),
}
}
func (display *Display) run() {
for {
select {
case formal := <-display.formal:
fmt.Println("Hello", formal.Name)
case western := <-display.western:
fmt.Println("Howdy", western.Name)
}
}
}
func main() {
var event json.RawMessage
env := EventEnvelope{
Event: &event,
}
if err := json.Unmarshal([]byte(input), &env); err != nil {
fmt.Print(err)
}
display := newDisplay()
go display.run()
events(display, event, env.Type)
}
func events(display *Display, raw json.RawMessage, event string) {
switch event {
case "hello":
hello := EventHello{}
if err := json.Unmarshal(raw, &hello); err != nil {
fmt.Println(err)
} else {
display.formal <- hello
}
case "howdy":
howdy := EventHowdy{}
if err := json.Unmarshal(raw, &howdy); err != nil {
fmt.Println(err)
} else {
display.western <- howdy
}
default:
fmt.Println("No event handler")
}
}
После отмены вызова EventEnvelope фактическое событие остается в качестве RawMessage. Событие RawMessage затем демаршалируется в указанный тип c. Может ли это быть Dynami c? Только если не было ошибок, мы должны отправить его на канал.
hello := EventHello{}
if err := json.Unmarshal(raw, &hello); err != nil {
fmt.Println(err)
} else {
display.formal <- hello
}
Тот же код на игровой площадке: https://play.golang.org/p/WPC8JAFyxgq