dalam pemahaman mengenai pengiraan bahasa Go: memori bersama dan
perangkap append()
Hai semua! Selamat datang ke blog saya. Sekiranya anda berada di sini, anda mungkin hanya bersentuhan dengan Golang, atau anda adalah pemaju yang berpengalaman, dan anda ingin memahami prinsip kerja dalaman bahagian ini. Oleh itu mari kita mulakan!
bahasa Go sangat dipuji kerana kesederhanaan dan kecekapannya -seperti orang sering berkata, "Bahasa Go adalah untuk menyelesaikan kerja." Bagi pemaju dari C, C atau Java dan bahasa lain, tatabahasa mudah dan kemudahan penggunaan bahasa Go menyegarkan. Walau bagaimanapun, walaupun dalam bahasa Go, beberapa ciri mungkin mengelirukan pemaju, terutamanya apabila memproses kepingan dan sub -klip. Mari kita memperkenalkan kehalusan ini dan lebih memahami bagaimana untuk mengelakkan perangkap biasa
dan dihiris untuk berkongsi ingatan.
append()
Biasanya, apabila anda memerlukan struktur data untuk menyimpan satu siri nilai, mengiris adalah pilihan pertama dalam bahasa Go. Fleksibiliti mereka berasal dari fakta seperti itu: panjangnya bukan sebahagian daripada jenisnya. Ciri ini mengatasi sekatan array, membolehkan kita membuat satu fungsi yang dapat mengendalikan mana -mana kepingan dan membolehkan kepingan itu meningkat atau berkembang mengikut keperluan. Walaupun kepingan mempunyai beberapa persamaan dengan array, seperti pengindeksan dan panjang, mereka mempunyai kaedah pengurusan data yang berbeza. Slice bertindak sebagai rujukan kepada array asas, yang sebenarnya menyimpan data kepingan. Pada dasarnya, kepingan memberikan pandangan beberapa atau semua elemen array. Oleh itu, apabila anda membuat kepingan, GO akan secara automatik memproses pelbagai bawah untuk mewujudkan elemen/data yang dihiris.
Memori bersama dihiris
Arahan adalah blok memori yang berterusan, tetapi apa yang membuatkan kepingan menarik adalah bagaimana mereka memetik ingatan ini. Mari memecahkan struktur kepingan:
Apabila anda membuat kepingan, ia mengandungi tiga komponen:
Puisi menunjuk kepada array yang mendasari
<code class="language-go">type slice struct { array unsafe.Pointer // 指向底层数组的指针 len int // 切片中的元素数量 cap int // 底层数组的容量 }</code>
Panjang penghirisan (bilangan elemen yang terkandung)
len
cap
Sebelum kita semakin mendalam, mari kita cuba memahami kapasiti penghirisan
. Apabila anda mendapat sub -plices dari penghirisan bahasa Go yang sedia ada, kapasiti
<code class="language-go">package main import "fmt" func main() { // 创建一个具有初始值的切片 original := []int{1, 2, 3, 4, 5} // 创建一个子切片——两个切片共享相同的底层数组! subslice := original[1:3] fmt.Println("未修改的子切片:", subslice) // 输出 => 未修改的子切片: [2 3] // 修改子切片 subslice[0] = 42 fmt.Println("原始切片:", original) // 输出 => 原始切片: [1 42 3 4 5] fmt.Println("修改后的子切片:", subslice) // 输出 => 修改后的子切片: [42 3] }</code>
Apabila anda membuat kepingan dari tatasusunan, panjang kepingan adalah bilangan elemen yang asalnya terkandung, dan kapasitinya adalah jumlah unsur yang dapat dikandung sebelum ia perlu berkembang.
apabila anda mendapat sub -slicing dari kepingan yang ada:
<code class="language-go">type slice struct { array unsafe.Pointer // 指向底层数组的指针 len int // 切片中的元素数量 cap int // 底层数组的容量 }</code>
subslice := original[1:4]
subslice
Kapasiti adalah 5-1 = 4, kerana ia bermula dari indeks 1 dan termasuk unsur-unsur hingga akhir kepingan asal. subslice
perangkap!
Perkongsian kapasiti yang tidak digunakan
append()
kapasiti
append()
mari kita pertimbangkan contoh ini:
Pada mulanya menunjuk kepada 2, 3, kapasiti adalah 4 (ia boleh tumbuh hingga akhir kepingan asal). Apabila anda menambah 60, 70 ke , ia menggunakan kapasiti lebihan kepingan asal.
dan
kedua -duanya mencerminkan perubahan ini kerana mereka berkongsi array yang sama.<code class="language-go">package main import "fmt" func main() { // 创建一个具有初始值的切片 original := []int{1, 2, 3, 4, 5} // 创建一个子切片——两个切片共享相同的底层数组! subslice := original[1:3] fmt.Println("未修改的子切片:", subslice) // 输出 => 未修改的子切片: [2 3] // 修改子切片 subslice[0] = 42 fmt.Println("原始切片:", original) // 输出 => 原始切片: [1 42 3 4 5] fmt.Println("修改后的子切片:", subslice) // 输出 => 修改后的子切片: [42 3] }</code>
subslice
Operasi diubahsuai kepingan asal kerana terdapat kapasiti yang cukup dalam array yang mendasari. Walau bagaimanapun, jika kita melebihi skop kapasiti atau unsur -unsur tambahan melebihi permit kapasiti, GO akan memperuntukkan array baru untuk sub -bahagian untuk memecahkan perkongsian dengan mengiris asal: subslice
Dalam kes ini, original
Amalan terbaik untuk mengelakkan perangkap subslice
menjelaskan kapasiti append()
<code class="language-go">func main() { // 原始切片 original := []int{1, 2, 3, 4, 5} // 创建一个子切片 subslice := original[1:4] // 指向元素 2, 3, 4 fmt.Println("子切片:", subslice) // 输出 => 子切片: [2 3 4] fmt.Println("子切片的长度:", len(subslice)) // 输出 => 子切片的长度: 3 fmt.Println("子切片的容量:", cap(subslice)) // 输出 => 子切片的容量: 4 }</code>
append()
kelebihan utama ialah:
i. Ini penting -bukan sekadar kepala seksyen baru, tetapi array baru dalam ingatan. ii. Ini seperti salinan fail dan bukannya berkongsi fail asal.
<code class="language-go">func main() { original := []int{1, 2, 3, 4, 5} subslice := original[1:3] // 指向元素 2, 3 fmt.Println("追加前原始切片:", original) // 输出 => [1 2 3 4 5] fmt.Println("追加前子切片:", subslice) // 输出 => [2 3] fmt.Println("子切片的容量:", cap(subslice)) // 输出 => 4 // 在容量范围内追加到子切片 subslice = append(subslice, 60, 70) // 追加到子切片后打印 fmt.Println("追加后原始切片:", original) // 输出 => [1 2 3 60 70] fmt.Println("追加后子切片:", subslice) // 输出 => [2 3 60 70] }</code>
Apabila lulus kepingan ke fungsi yang tidak boleh mengubah suai data asal, pertimbangkan bukan kebolehpasaran
make([]int, len(subslice))
kelebihan utama ialah: copy()
III.
ingat:Slice adalah rujukan kepada array yang mendasari
append()
<code class="language-go">type slice struct { array unsafe.Pointer // 指向底层数组的指针 len int // 切片中的元素数量 cap int // 底层数组的容量 }</code>
Adakah anda fikir sumber ini membantu? Adakah anda mempunyai soalan? Atau adakah anda menemui ralat atau kesilapan? Sila tinggalkan maklum balas anda dalam komen.
Jangan lupa untuk berkongsi sumber ini dengan orang lain yang mungkin mendapat manfaat daripadanya. Ikuti saya untuk mendapatkan lebih banyak maklumat.
Atas ialah kandungan terperinci Pergi kepingan dan subslic: Memahami memori bersama dan mengelakkan `tambah ()` perangkap. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!