Удалить элемент в срезе
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
Хорошо, неважно. Правильный ответ на эту тему, но неправильный ответ на вопрос.