Я хочу научиться программировать в Go, я решил в качестве домашнего животного программ я хотел бы сделать простой диспетчеру различных команд до нескольких CommandHandler (если CommandHandler имеет то же имя, что и команда должны обрабатывать.)Как отправить команды вправо CommandHandler по композиции наследования Голанг?
Моих проблема в том, что когда я хочу иметь CommandHandlerManager, который публикует команды, которые будут отправлять правильному CommandHandler, он говорит мне, что мне нужно иметь конкретную реализацию моего HelloWorldCommand, потому что HelloWorldCommandHandler не реализует интерфейс Command. сообщение
Ошибка при компиляции
E:\Desktop\ManBear\golang\src>go run main.go
# command-line-arguments
.\main.go:71: cannot use cmdHandler (type HelloWorldCommandHandler) as type CommandHandler in array or slice literal:
HelloWorldCommandHandler does not implement CommandHandler (wrong type for Handle method)
have Handle(HelloWorldCommand)
want Handle(Command)
я должен был бы, что кто-то объясняет мне, что я делаю неправильно, я предположил, что это означало, что я должен реализовать метод в одиночку функ к моему HelloWorldCommandHandler для интерфейс, как показано ниже:
func (ch HelloWorldCommandHandler) Handle(cmd Command) {
fmt.Println("HelloWorldCommandHandler handled the basic command with name --> " + cmd.GetName())
}
Но это создало больше ошибок, связанных с типом.
Рабочий пример того, что я пытаюсь сделать с объяснением того, как и почему я делаю это неправильно, будет оценен.
спасибо.
Вот мой код:
package main
import (
"fmt"
"strconv"
)
type Command interface {
GetName() string
}
type CommandHandler interface {
Command
Handle(cmd Command)
}
type HelloWorldCommand struct {
Command
Name string
Age int
}
func (cmd HelloWorldCommand) GetName() string {
return "HelloWorldCommand"
}
type HelloWorldCommandHandler struct {
CommandHandler
}
func (cmd HelloWorldCommandHandler) GetName() string {
return "HelloWorldCommand"
}
func (ch HelloWorldCommandHandler) Handle(cmd HelloWorldCommand) {
fmt.Println("Hello World! My name is " + cmd.Name + " and I'm " + strconv.Itoa(cmd.Age) + " years old!")
}
type CommandHandlerManager struct {
CommandHandlers []CommandHandler
}
func (chm CommandHandlerManager) Publish(cmd Command) {
for _, cmdHandler := range chm.CommandHandlers {
if cmd.GetName() == cmdHandler.GetName() {
cmdHandler.Handle(cmd)
}
}
}
func main() {
fmt.Println("Hey my friend!")
cmd := HelloWorldCommand {Name: "ManBear", Age: 357}
cmdHandler := HelloWorldCommandHandler {}
fmt.Println(cmd.GetName())
fmt.Println(cmdHandler.GetName())
cmdHandler.Handle(cmd)
cmdHandlerManager := CommandHandlerManager {
CommandHandlers: []CommandHandler {
cmdHandler, // <-- the error is here
},
};
}
UPDATE:
Для любопытных, вот версия functionning моей любимой программы
Благодаря помощи от Dean Elbaz предлагая использовать утверждение типа, он позволяет обрабатывать команду с помощью правильного CommandHandler и использовать правильный набор значений, который прилагается к каждой команде.
package main
import (
"fmt"
"strconv"
"time"
)
type Command interface {
GetName() string
}
type CommandHandler interface {
Command
Handle(cmd Command)
}
const HelloWorldCommandName string = "HelloWorldCommand"
type HelloWorldCommand struct {
Command
Name string
Age int
}
func (cmd HelloWorldCommand) GetName() string {
return HelloWorldCommandName
}
// Basic Hello World
type HelloWorldCommandHandler struct {
CommandHandler
}
func (cmd HelloWorldCommandHandler) GetName() string {
return HelloWorldCommandName
}
func (ch HelloWorldCommandHandler) Handle(cmd Command) {
fmt.Println("Hello World!\n----------------------------------------\n")
}
// Hello World with Name and Age
type HelloWorldWithNameAndAgeCommandHandler struct {
CommandHandler
}
func (cmd HelloWorldWithNameAndAgeCommandHandler) GetName() string {
return HelloWorldCommandName
}
func (ch HelloWorldWithNameAndAgeCommandHandler) Handle(cmd Command) {
var helloWorldCommand HelloWorldCommand = cmd.(HelloWorldCommand)
fmt.Println("Hello World! My name is " + helloWorldCommand.Name + " and I'm " + strconv.Itoa(helloWorldCommand.Age) + " years old!\n----------------------------------------\n")
}
const TodayDateTimeCommandName string = "TodayDateTimeCommand"
// Today's DateTime Command
type TodayDateTimeCommand struct {
Command
TimeZone string
}
func (cmd TodayDateTimeCommand) GetName() string {
return TodayDateTimeCommandName
}
type TodayDateTimeCommandHandler struct {
}
func (ch TodayDateTimeCommandHandler) GetName() string {
return TodayDateTimeCommandName
}
func (ch TodayDateTimeCommandHandler) Handle(cmd Command) {
var todayCommand TodayDateTimeCommand = cmd.(TodayDateTimeCommand)
location, err := time.LoadLocation(todayCommand.TimeZone)
if err != nil {
fmt.Errorf("Could not load the Location of the TimeZone. %f", err.Error())
return
}
current_time := time.Now().In(location)
fmt.Println("Today's date and time is " + current_time.String() + " for the time zone: " + todayCommand.TimeZone)
}
// The CommandHandler Manager
type CommandHandlerManager struct {
CommandHandlers []CommandHandler
}
func (chm CommandHandlerManager) Publish(cmd Command) {
for _, cmdHandler := range chm.CommandHandlers {
if cmd.GetName() == cmdHandler.GetName() {
cmdHandler.Handle(cmd)
}
}
}
func main() {
fmt.Println("Hey my friend!\n\n\n")
cmdHandlerManager := CommandHandlerManager {
CommandHandlers: []CommandHandler {
HelloWorldCommandHandler {},
HelloWorldWithNameAndAgeCommandHandler {},
TodayDateTimeCommandHandler {},
},
};
cmd := HelloWorldCommand {Name: "ManBear", Age: 357}
cmdHandlerManager.Publish(cmd)
fmt.Println("~~~~~~~~ other command published ~~~~~~~~~~~~~~~~~~~~~")
cmd2 := TodayDateTimeCommand{ TimeZone: "America/Montreal" }
cmdHandlerManager.Publish(cmd2)
}
Благодарим вас за «Утверждение типа», оно, похоже, работает для моей цели. – HexaGridBrain