func main() {
a := []string{"Hello1", "Hello2", "Hello3"}
fmt.Println(a)
// [Hello1 Hello2 Hello3]
a = append(a[:0], a[1:]...)
fmt.Println(a)
// [Hello2 Hello3]
}
Bagaimana cara menghapus trik ini dengan fungsi append berfungsi?
Tampaknya itu meraih segalanya sebelum elemen pertama (array kosong)
Kemudian menambahkan semuanya setelah elemen pertama (posisi nol)
Apa yang ... (dot dot dot) lakukan?
...
dijelaskan di sana secara detail?Jawaban:
Di mana
a
slice, dani
indeks elemen yang ingin Anda hapus:...
adalah sintaks untuk argumen variadic di Go.Pada dasarnya, ketika mendefinisikan suatu fungsi, ia menempatkan semua argumen yang Anda masukkan ke dalam satu irisan jenis itu. Dengan melakukan itu, Anda dapat memberikan argumen sebanyak yang Anda inginkan (misalnya,
fmt.Println
dapat mengambil argumen sebanyak yang Anda inginkan).Sekarang, ketika memanggil fungsi,
...
lakukan yang sebaliknya: ia membongkar sebuah slice dan meneruskannya sebagai argumen terpisah ke fungsi variadic.Jadi apa yang dilakukan garis ini:
pada dasarnya:
Sekarang, Anda mungkin bertanya-tanya, mengapa tidak lakukan saja
Nah, definisi fungsi
append
adalahJadi argumen pertama harus berupa irisan dari tipe yang benar, argumen kedua adalah variadic, jadi kami meneruskan irisan kosong, dan kemudian membongkar sisa slice untuk mengisi argumen.
sumber
a = append(a[:i], a[i+1:]...)
Ada dua opsi:
A: Anda peduli tentang mempertahankan pesanan array:
B: Anda tidak peduli tentang mempertahankan pesanan (ini mungkin lebih cepat):
Lihat tautan untuk melihat implikasi kebocoran memori jika array Anda adalah petunjuk.
https://github.com/golang/go/wiki/SliceTricks
sumber
Daripada memikirkan indeks dalam
[a:]
-,[:b]
- dan-[a:b]
catatan sebagai indeks elemen, anggap mereka sebagai indeks kesenjangan di sekitar dan di antara elemen, dimulai dengan celah yang diindeks0
sebelum elemen diindeks sebagai0
.Melihat angka biru saja, akan lebih mudah untuk melihat apa yang sedang terjadi:
[0:3]
menutup semuanya,[3:3]
kosong dan[1:2]
akan menghasilkan{"B"}
. Kemudian[a:]
hanya versi pendek[a:len(arrayOrSlice)]
,[:b]
versi pendek[0:b]
dan[:]
versi pendek[0:len(arrayOrSlice)]
. Yang terakhir ini biasanya digunakan untuk mengubah array menjadi slice saat dibutuhkan.sumber
... adalah sintaks untuk argumen variadic.
Saya pikir ini diimplementasikan oleh complier menggunakan slice (
[]Type)
, sama seperti fungsi append:ketika Anda menggunakan "elems" di "append", sebenarnya itu adalah slice ([] type). Jadi "
a = append(a[:0], a[1:]...)
" berarti "a = append(a[0:0], a[1:])
"a[0:0]
adalah sepotong yang tidak memiliki apa-apaa[1:]
adalah "Hello2 Hello3"Begini Cara kerjanya
sumber
a[0:0]
tidak lainnil
adalah sepotong dengan panjang 0.a[0:0]
akan hanya menjadinil
jikaa
adalahnil
.Saya mendapatkan indeks di luar rentang kesalahan dengan solusi jawaban yang diterima. Alasan: Ketika rentang mulai, itu bukan nilai iterate satu per satu, iterate by index. Jika Anda memodifikasi sepotong saat berada dalam jangkauan, itu akan menimbulkan beberapa masalah.
Jawaban lama:
Diharapkan:
Sebenarnya:
Cara yang Benar (Solusi):
Sumber: https://dinolai.com/notes/golang/golang-delete-slice-item-in-range-problem.html
sumber
Dalam wiki golang itu menunjukkan beberapa trik untuk slice, termasuk menghapus elemen dari slice.
Tautan: masukkan deskripsi tautan di sini
Misalnya a adalah irisan yang ingin Anda hapus elemen angka i.
ATAU
sumber