douxie2029 2018-07-25 23:57
浏览 371
已采纳

GoLang追加到嵌套切片

In GoLang, having the following structs and methods, I'm trying to append to a slice that belongs to a struct that is nested in another struct:

/* Tiers agent struct */
type Agent struct {
    Registration string
}

/* Tiers queue struct */
type Queue struct {
    Name string
    Agents []Agent
}

/* Tiers struct */
type Tiers struct {
    Queues []Queue
}

func (Q *Queue) AddAgent (agent_registration string) {

    Q.Agents = append(Q.Agents, Agent{Registration: agent_registration})
}

func (T *Tiers) AddQueue(queue_name string, agent_registration string) {

    var cur_queue *Queue

    found_queue := false

    /* Find queue by queue name */
    for _ , queue := range T.Queues {
        if queue.Name == queue_name {
            found_queue = true
            cur_queue = &queue
        }
    }

    /* If queue not found, create a new one */
    if found_queue == false {
        T.Queues = append(T.Queues, Queue{Name: queue_name})
        cur_queue = &(T.Queues[len(T.Queues)-1])
    }

    /* Add agent to queue (add tier) */
    cur_queue.AddAgent(agent_registration)
}

My business rule is that I'll receive lots of {queue_name, agent_name} pairs and I want to build a structure that groups all agents that shares the same 'queue_name'. So, in the end of day I want something like:

Queue1: ['agent1', 'agent2', 'agent3', ...] Queue2: ['agent4', 'agent5', ...]

I'm modeling this using the structs I've mentioned above. The problem is when I try to add agents to a queue only the last insertion persists. Example:

tiers.AddQueue('suport@default', '1000@default')
tiers.AddQueue('suport@default', '1003@default')
tiers.AddQueue('suport@default', '1001@default')

Output: {[{support@default [{1001@default}]}]}

When what I want is that the output be:

Output: {[{support@default [{1000@default},{1003@default}, {1001@default}]}]}

  • 写回答

1条回答 默认 最新

  • doubaoxue5788 2018-07-26 00:47
    关注

    Your problem is that this:

    for _ , queue := range T.Queues {
    

    copies values from T.Queues into queue, then you take the address of that copy:

    cur_queue = &queue
    

    and end up modifying the copy while leaving the Queue in the T.Queues slice alone.

    An easy solution would be to use the for i := range ... form of the loop and take the address of the Queue in the slice rather than the copy:

    for i := range T.Queues {
        if T.Queues[i].Name == queue_name {
            found_queue = true
            cur_queue = &T.Queues[i]
        }
    }
    

    You could also use a slice of pointers and go back to your

    for _ , queue := range T.Queues {
    

    loop with queue already being a pointer.

    You might want to break out of the loop early once you've found something. If T.Queues is expected to be large you might want to switch to a map so that you don't have so many linear searches.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作