如何创建可以访问结构体值的事件处理程序?

问题描述 投票:0回答:1

我有一个带有事件处理程序管理器的控制器(名称为“实例”)。

我还有一些其他控制器(类型不固定),其中包含一些信息。

当控制器“实例”调用处理函数时,回调函数必须访问其他控制器的信息。

最好的方法是什么?

我这样做了,但我不知道这是否是最好的方法:

package main

import (
    "fmt"
    "time"
)

// ******************************************
type SetEvent func(val int)

type Instance struct {
    handlers []SetEvent
}

func NewInstance() *Instance {
    ins := Instance{}
    ins.handlers = make([]SetEvent, 0)
    return &ins
}

func (ins *Instance) AddHandler(handler SetEvent) {
    ins.handlers = append(ins.handlers, handler)
}

func (ins *Instance) Start() {
    go func() {
        i := 0
        for {
            for j := range ins.handlers {
                ins.handlers[j](i)
            }
            i++
            time.Sleep(time.Second)
        }
    }()
}

// *******************************************
type Instance2 struct {
    val int
}

func NewInstance2(val int) *Instance2 {
    ins := Instance2{}
    ins.val = val
    return &ins
}

// *******************************************
type Instance3 struct {
    str string
}

func NewInstance3(val string) *Instance3 {
    ins := Instance3{}
    ins.str = val
    return &ins
}

// *******************************************
func main() {
    b := NewInstance2(10)
    c := NewInstance3("Hello")

    a := NewInstance()

    a.AddHandler(func(val int) {
        fmt.Printf("Instance2.SetEvent %d / %d\n", val, b.val)
    })
    a.AddHandler(func(val int) {
        fmt.Printf("Instance3.SetEvent %d / %s\n", val, c.str)
    })

    a.Start()

    for {
        fmt.Printf("Main.run\n")
        time.Sleep(time.Second)
    }
}

https://go.dev/play/p/6lEOwGT1gjg

go events handler
1个回答
0
投票

您可能需要使用

Interface
来执行此操作。

type Controller interface {
    Handle(value int)
}

// ************** Manager **************
type Manager struct {
    controllers []Controller
}

func NewManager() *Manager {
    return &Manager{
        controllers: []Controller{},
    }
}

func (m *Manager) AddController(c Controller) {
    m.controllers = append(m.controllers, c)
}

func (m *Manager) Start() {
    go func() {
        i := 0
        for {
            for _, controller := range m.controllers {
                controller.Handle(i)
            }
            i++
            time.Sleep(time.Second)
        }
    }()
}

// ************** Controller 1 **************
type C1 struct {
    val int
}

func NewC1(val int) *C1 {
    return &C1{
        val: val,
    }
}

func (c *C1) Handle(value int) {
    fmt.Printf("C1 with value: %d, handling: %d\n", c.val, value)
}

// ************** Controller 2 **************
type C2 struct {
    val string
}

func (c *C2) Handle(value int) {
    fmt.Printf("C2 with value: %s, handling: %d\n", c.val, value)
}

func NewC2(val string) *C2 {
    return &C2{
        val: val,
    }
}

func main() {
    c1 := NewC1(10)
    c2 := NewC2("Hello")

    a := NewManager()

    a.AddController(c1)
    a.AddController(c2)
    a.Start()

    for {
        fmt.Printf("Main.run\n")
        time.Sleep(time.Second)
    }
}

控制器自行访问其字段,无需使控制器的字段可供 Manager 访问。

我不确定这是否是最好的方法,但对我来说看起来更好。如果您有任何需要,请进一步询问。

© www.soinside.com 2019 - 2024. All rights reserved.