GoLang, плохое показание из среза - PullRequest
0 голосов
/ 09 сентября 2018

Я довольно новичок в GoLang, и мне нужна помощь. Я делаю простое приложение API.

вставка структур API в слайс выглядит следующим образом:

type Struct struct {
    //some records
}

var structs []Struct //slice

func SetStruct(w http.ResponseWriter, req *http.Request) {
    var st Struct
    decoder := json.NewDecoder(req.Body)
    decoder.Decode(&st)
    emails = append(structs, st)
    json.NewEncoder(w).Encode(structs)
}

И эта функция работает нормально.

Второе, что я хочу сделать, - это удаление структур из среза, зависит от NR параметра. Я называю это POST. Метод выглядит так:

func SendStruct(w http.ResponseWriter, req *http.Request) {
    var st Email
    decoder := json.NewDecoder(req.Body)
    decoder.Decode(&st)
    for i, item := range emails {
        if item.NR == st.NR {
            structs = append(structs[:i], structs[i+1:]...)
            //if numbers match, delete from slice emails
        }
    }
    json.NewEncoder(w).Encode(emails)
}

И это работает довольно хорошо, когда у меня есть Scenerio, например (например):

{"NR": "22"}
{"NR": "33"}
{"NR": "22"}

Когда я хочу удалить "33", это работает довольно хорошо. Когда я хочу удалить "22" (оба), все становится сложным, потому что, когда я передаю 22, приложение вылетает.

В item.NR (из SendStruct) я получаю переменную вне диапазона. Когда я добавляю break paarmetr в for, он работает нормально, но я могу только удалять структуры по одному. Я хочу удалить все 22 в одном вызове API. Ошибка, которую я получаю:

http: обслуживание паники [:: 1]: 52163: ошибка времени выполнения: границы среза вне диапазона

Спасибо за любые советы!

1 Ответ

0 голосов
/ 09 сентября 2018

Вы не должны изменять фрагменты, пока вы выполняете их. range не знает, что срез теперь короче, чем был на момент его начала, поэтому в конечном итоге он пытается выполнить итерацию за этой точкой и - упс! - больше нет кусочка, который можно найти.

Вместо этого я бы порекомендовал сохранить отдельный слайс со списком индексов, в которых можно найти элемент, который нужно удалить. Затем, когда вы закончите итерацию по фрагменту электронной почты, вы можете выполнить итерацию по этому фрагменту отслеживания индекса и удалить соответствующие элементы. Убедитесь, что вы сортируете срез индекс-трекера так, чтобы он переходил от высоких индексов к низким индексам, иначе вы в конечном итоге сократите срез относительно того места, где находятся остальные точки индекса.

...