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 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?