douou1891 2015-12-16 23:33
浏览 16

goroutine频道对切片进行了突变后,如何获得切片的新索引?

I'm wondering how I can get an elements new index in a slice, I have a function that gets applications from a database, and queries for certain ones (for filtering) but when I query for ones and I get ones I don't need, I'm trying to remove them from the slice so that only the wanted ones make it to the view. It's working but I'm having a problem with the index's in the goroutines are the older index's so when it trys to remove the element from the slice it panics: Anyways here is my code:

// ListApplications will list the applications
func ListApplications(w http.ResponseWriter, r *http.Request) {
    session := common.Sesh(r)
    urlParse, err := url.ParseRequestURI(r.RequestURI)
    vals := urlParse.Query()

    if err != nil {
        log.Println(err)
    }
    if lvl, ok := session.Values["user_level"]; !ok || lvl.(int) < 3 {
        http.Redirect(w, r, "/", 401)
        return
    }

    db := common.Db()

    type UserResp struct {
        Action string
        I      int
        User   common.User
    }
    apps := []common.Application{}
    resp := make(chan UserResp)
    db.Order("accepted asc").Order("created_at asc").Find(&apps)
    var wg sync.WaitGroup
    for i, app := range apps {
        wg.Add(1)
        go func(i int, app common.Application) {
            user := common.User{}
            if vals.Get("class") != "" {
                db.Preload("Characters", "character_class = ?", vals.Get("class")).Model(&app).Related(&user)
                if len(user.Characters) == 0 {
                    resp <- UserResp{"remove", i, user}
                } else {
                    resp <- UserResp{"add", i, user}
                }
                wg.Done()
                return
            }

            db.Preload("Characters").Model(&app).Related(&user)
            log.Println(user)
            resp <- UserResp{"add", i, user}
            wg.Done()
        }(i, app)
    }

    go func() {
        wg.Wait()
        close(resp)
    }()

    for user := range resp {
        switch user.Action {
        case "add":
            apps[user.I].User = user.User
        case "remove":
        log.Println(len(apps), user.I)
            apps = append(apps[:user.I], apps[user.I+1:]...)
        }
    }

    common.View(w, r, "/application/list", &struct {
        Title string
        Apps  []common.Application
    }{"Viewing Applications", apps})
}

The for user := range resp is where I'm trying to delete under the "remove" action. But like I said, the index getting passed through on the channel is out dated sometimes so how can I maintain a persistent index in my goroutines

  • 写回答

1条回答 默认 最新

  • douqiao5552 2015-12-16 23:40
    关注

    Don't range over a slice if you want to remove elements from it.

    Instead, loop over the slice by index:

    // Removes 2 from slice.
    slice := []int{1,2,3}
    for i := 0; i < len(slice); i++ {
        if slice[i] == 2 {
            slice = append(slice[:i], slice[i+1:]...)
            i--
        }
    }
    fmt.Println(slice) // [1 3]
    

    The point is bringing the index cursor back by one (so it won't go forward) after you've removed the current element.

    评论

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c