Удалить элемент в срезе

func main() {
    a := []string{"Hello1", "Hello2", "Hello3"}
    fmt.Println(a)
    // [Hello1 Hello2 Hello3]
    a = append(a[:0], a[1:]...)
    fmt.Println(a)
    // [Hello2 Hello3]
}

Как это удалить трюк с помощью функции добавления?

Казалось бы, он захватывает все до первого элемента (пустой массив)

Затем добавьте все после первого элемента (нулевой позиции)

Что делает... (точка точка)?

Ответ 1

Где a - это срез, а i - это индекс элемента, который вы хотите удалить:

a = append(a[:i], a[i+1:]...)

... является синтаксисом для вариационных аргументов в Go.

В принципе, когда определяет функцию, она помещает все аргументы, которые вы передаете в один фрагмент этого типа. Делая это, вы можете передать столько аргументов, сколько хотите (например, fmt.Println может принимать столько аргументов, сколько вы хотите).

Теперь, когда вызывает функцию, ... делает обратное: она распаковывает срез и передает их как отдельные аргументы в переменную функцию.

Итак, что делает эта строка:

a = append(a[:0], a[1:]...)

по существу:

a = append(a[:0], a[1], a[2])

Теперь вам может быть интересно, почему бы просто не сделать

a = append(a[:1]...)

Ну, определение функции append равно

func append(slice []Type, elems ...Type) []Type

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

Ответ 2

Есть два варианта:

A: Вы заботитесь о сохранении порядка массива:

a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]

B: Вы не заботитесь о сохранении порядка (это, вероятно, быстрее):

a[i] = a[len(a)-1] // Replace it with the last one.
a = a[:len(a)-1]   // Chop off the last one.

См. ссылку, чтобы увидеть последствия утечек памяти, если ваш массив имеет указатели.

https://github.com/golang/go/wiki/SliceTricks

Ответ 3

... является синтаксисом для вариационных аргументов.

Я думаю, что это реализовано complier, используя slice ([]Type), как и функция append:

func append(slice []Type, elems ...Type) []Type

когда вы используете "elems" в "append", на самом деле это тип slice ([]). Итак, "a = append(a[:0], a[1:]...)" означает "a = append(a[0:0], a[1:])"

a[0:0] - это срез, который не имеет ничего

a[1:] есть "Hello2 Hello3"

Вот как это работает

Ответ 4

Или, поскольку вы пытаетесь найти индекс элемента, который будет удален в любом случае,

// na = new a, da = a that to be deleted
var na []string
for _, v := range a {
    if v == da {
        continue
    } else {
        na = append(na, v)
    }
}
a = na

Хорошо, неважно. Правильный ответ на эту тему, но неправильный ответ на вопрос.