Saya mencoba menggabungkan irisan [1, 2]
dan irisan [3, 4]
. Bagaimana saya bisa melakukan ini di Go?
Saya mencoba:
append([]int{1,2}, []int{3,4})
tapi punya:
cannot use []int literal (type []int) as type int in append
Namun, dokumentasi sepertinya mengindikasikan ini mungkin, apa yang saya lewatkan?
slice = append(slice, anotherSlice...)
go
append
slice
variadic-functions
Kevin Burke
sumber
sumber
append()
fungsi variadic, dan...
memungkinkan Anda melewati beberapa argumen ke fungsi variadic dari slice.foo()
contoh di atas,is
parameter menyimpan salinan irisan asli, yang artinya memiliki salinan referensi ringan ke array, len dan tutup yang sama yang mendasarinya. Jikafoo
fungsi mengubah anggota, perubahan akan terlihat pada aslinya. Ini demo . Jadi, satu-satunya overhead nyata adalah membuat irisan baru jika Anda belum memilikinya, seperti:foo(1, 2, 3, 4, 5)
yang akan membuat irisan baru yangis
akan menampung....
pada irisan yang ada, itu hanya melewati irisan itu. Ketika Anda melewati argumen individual, itu mengumpulkan mereka ke dalam irisan baru dan meneruskannya. Saya tidak memiliki pengetahuan tangan pertama dari mekanisme yang tepat, tapi saya akan menebak bahwa ini:foo(1, 2, 3, 4, 5)
dan ini:func foo(is ...int) {
hanya de-gula ini:foo([]int{1, 2, 3, 4, 5})
dan ini:func foo(is []int) {
.Jawaban untuk pertanyaan Anda adalah contoh
s3 := append(s2, s0...)
dalam Spesifikasi Bahasa Pemrograman Go . Sebagai contoh,sumber
a[low : high : max]
) yang juga menentukan kapasitas maksimum . Sebagai contoh, slicea[0:2:4]
akan memiliki kapasitas4
dan tidak dapat disambung ulang untuk memasukkan elemen di luar itu, bahkan jika array backing memiliki seribu elemen setelahnya.Tidak ada yang bertentangan dengan jawaban lain, tetapi saya menemukan penjelasan singkat di dokumen lebih mudah dimengerti daripada contoh di dalamnya:
sumber
Saya pikir sangat penting untuk menunjukkan dan mengetahui bahwa jika irisan tujuan (irisan yang Anda tambahkan) memiliki kapasitas yang cukup, append akan terjadi "di tempat", dengan reslicing tujuan (reslicing untuk menambah panjangnya agar menjadi mampu mengakomodasi elemen-elemen yang dapat ditambahkan).
Ini berarti bahwa jika tujuan dibuat dengan mengiris array atau irisan yang lebih besar yang memiliki elemen tambahan di luar panjang irisan yang dihasilkan, mereka mungkin akan ditimpa.
Untuk menunjukkan, lihat contoh ini:
Output (coba di Go Playground ):
Kami membuat array "dukungan"
a
dengan panjang10
. Kemudian kita membuatx
irisan tujuan dengan mengirisa
array ini ,y
irisan dibuat menggunakan literal komposit[]int{3, 4}
. Sekarang ketika kita menambahkany
untukx
, hasilnya adalah diharapkan[1 2 3 4]
, tapi apa yang mungkin mengejutkan adalah bahwa array dukungana
juga berubah, karena kapasitasx
yaitu10
yang cukup untuk menambahkany
untuk itu, jadix
ini resliced yang juga akan menggunakan yang samaa
berbagai dukungan, danappend()
akan menyalin elemeny
ke sana.Jika Anda ingin menghindari ini, Anda dapat menggunakan ekspresi irisan penuh yang memiliki formulir
yang membangun slice dan juga mengontrol kapasitas slice yang dihasilkan dengan mengaturnya
max - low
.Lihat contoh yang dimodifikasi (satu-satunya perbedaan yang kita buat
x
seperti inix = a[:2:2]
::Output (coba di Go Playground )
Seperti yang Anda lihat, kami mendapatkan
x
hasil yang sama tetapi array backinga
tidak berubah, karena kapasitasx
"hanya"2
(terima kasih kepada ekspresi irisan penuha[:2:2]
). Jadi untuk melakukan append, array backing baru dialokasikan yang dapat menyimpan elemen keduanyax
dany
, yang berbeda daria
.sumber
Saya ingin menekankan jawaban @icza dan menyederhanakannya karena ini adalah konsep yang sangat penting. Saya berasumsi bahwa pembaca sudah terbiasa dengan irisan .
Ini adalah jawaban yang valid untuk pertanyaan itu. TETAPI jika Anda perlu menggunakan irisan 'a' dan 'c' nanti dalam kode dalam konteks yang berbeda, ini bukan cara yang aman untuk menggabungkan irisan.
Untuk menjelaskan, mari kita baca ekspresi bukan dalam hal irisan, tetapi dalam hal array yang mendasarinya:
append () tidak harus membuat array baru! Ini dapat menyebabkan hasil yang tidak terduga. Lihat contoh Go Playground .
Selalu gunakan fungsi make () jika Anda ingin memastikan bahwa array baru dialokasikan untuk slice. Misalnya di sini ada beberapa opsi yang jelek tapi cukup efisien untuk tugas tersebut.
sumber
append () berfungsi dan operator spread
Dua irisan dapat digabungkan menggunakan
append
metode di perpustakaan standar golang. Yang mirip denganvariadic
operasi fungsi. Jadi kita perlu menggunakan...
sumber
append([]int{1,2}, []int{3,4}...)
akan bekerja. Melewati argumen ke...
parameter.Jika
f
variadic dengan parameterp
tipe terakhir...T
, maka dif
dalam tipep
itu sama dengan type[]T
.Jika
f
dipanggil tanpa argumen aktual untukp
, nilai yang diteruskanp
adalahnil
.Jika tidak, nilai yang diteruskan adalah irisan tipe
[]T
baru dengan larik dasar baru yang elemen berurutannya adalah argumen aktual, yang harus ditetapkan oleh semua orangT
. Panjang dan kapasitas irisan karena itu adalah jumlah argumen yang terikatp
dan mungkin berbeda untuk setiap situs panggilan.Diberi fungsi dan panggilan
sumber