zoukankan      html  css  js  c++  java
  • golang list使用 双层 循环 删除 遍历

    queue队列:

    import (
        "container/list"
        "sync"
    )
    
    type Queue struct {
        l *list.List
        m sync.Mutex
    }
    
    func NewQueue() *Queue {
        return &Queue{l: list.New()}
    }
    
    func (q *Queue) PushBack(v interface{}) {
        if v == nil {
            return
        }
        q.m.Lock()
        defer q.m.Unlock()
        q.l.PushBack(v)
    }
    
    func (q *Queue) Front() *list.Element {
        q.m.Lock()
        defer q.m.Unlock()
        return q.l.Front()
    }
    
    func (q *Queue) Remove(e *list.Element) {
        if e == nil {
            return
        }
        q.m.Lock()
        defer q.m.Unlock()
        q.l.Remove(e)
    }
    
    func (q *Queue) Len() int {
        q.m.Lock()
        defer q.m.Unlock()
        return q.l.Len()
    }
    

    这样就基本满足了.

    使用过程中, 发现list有个小坑: 遍历的时候不能Remove

    for e := l.Front(); e != nil; e = e.Next {
        l.Remove(e)
    }
    

    按照设想, 这应该会移除list里所有的元素, 但是, 结果是只移除了第一个. 原因是: Remove时候, e.next = nil, 使得for判断中, e != nil不成立了, 所以退出了循环.
    这时候有两种解决办法:

    var next *list.Element
    for e := l.Front(); e != nil; e = next {
        next = e.Next()
        l.Remove(e)
    }
    
    for {
        e := l.Front()
        if e == nil {
                break
        }
        l.Remove(e)
    }

    如果是双层循环删除的话, 注意如果第二个循环删除的元素在第一个删除的元素后一位, 需要再前进一位:
    if j == nexte {
    nexte = nexte.Next()
    }
     
  • 相关阅读:
    < high performance web sites > 阅读小记
    Gimp制作圆角透明图片
    iphone开发小记
    Android开发小记
    双网卡绑定(suse)
    xen虚拟机操作整理
    linux网络相关命令使用
    lua协程并发下载简单测试
    linux使用技巧(shell/vi/screen)
    爬虫之scrapy框架
  • 原文地址:https://www.cnblogs.com/mafeng/p/10794859.html
Copyright © 2011-2022 走看看