Rumah > Artikel > pembangunan bahagian belakang > hirisan nil, hirisan bukan nol, hirisan kosong dalam bahasa Go
Editor PHP Xiaoxin membawakan anda pengenalan kepada jenis kepingan dalam bahasa Go. Dalam bahasa Go, hirisan mempunyai tiga keadaan: hirisan nil, hirisan bukan nol dan hirisan kosong. Ketiga-tiga keadaan penghirisan ini mempunyai maksud dan ciri yang berbeza apabila digunakan. Memahami perbezaan antara jenis hirisan ini akan membantu kami lebih memahami dan menggunakan fungsi hirisan dalam bahasa Go. Seterusnya, mari kita terokai ciri khusus dan kegunaan ketiga-tiga jenis kepingan ini.
Saya baru dalam pengaturcaraan Go. Saya membaca dalam buku pengaturcaraan Go bahawa kepingan terdiri daripada tiga bahagian: penunjuk kepada tatasusunan, panjang dan kapasiti.
Saya keliru tentang perkara berikut:
Boleh sesiapa beritahu saya jika tiada dan kepingan kosong adalah perkara yang sama? Jika kedua-duanya berbeza, sila beritahu saya apa perbezaan antara kedua-duanya? Bagaimana untuk menguji sama ada sekeping kosong? Juga, apakah nilai yang dipegang oleh penunjuk dalam kepingan bukan sifar dengan panjang dan kapasiti sifar?
nil
tidak sama dengan kepingan kosong (kapasiti 0), tetapi tingkah laku yang boleh diperhatikan adalah sama (hampir selalu). Apa yang saya maksudkan ialah:
len()
和 cap()
terbina dalamfor range
mengatasinya (akan menjadi 0 lelaran) Lihat contoh mudah ini (satu nil
切片和 2 个非 nil
keping dan 2 bukan
var s1 []int // nil slice s2 := []int{} // non-nil, empty slice s3 := make([]int, 0) // non-nil, empty slice fmt.Println("s1", len(s1), cap(s1), s1 == nil, s1[:], s1[:] == nil) fmt.Println("s2", len(s2), cap(s2), s2 == nil, s2[:], s2[:] == nil) fmt.Println("s3", len(s3), cap(s3), s3 == nil, s3[:], s3[:] == nil) for range s1 {} for range s2 {} for range s3 {}Output (cuba di Go Playground):
s1 0 0 true [] true s2 0 0 false [] false s3 0 0 false [] false
nil
切片进行切片会生成 nil
切片,对非 nil
切片进行切片会生成非 nil
(Perhatikan bahawa menghiris sekeping menghasilkan sekeping , dan menghiris sekeping bukan nil
进行比较来区分,它们在其他方面的行为都是相同的。 但请注意,许多软件包确实会将切片与 nil
进行比较,并且可能会基于此进行不同的操作(例如 encoding/ json
和 fmt
menghasilkan sekeping bukan .)
, mereka sebaliknya berkelakuan sama. Tetapi ambil perhatian bahawa banyak pakej membandingkan kepingan dengan dan mungkin melakukan perkara secara berbeza berdasarkan itu (cth. pengekodan/ json
dan fmt
pakej). nil
切片转换为数组指针将生成非 nil
指针,将 nil
切片转换为数组指针将生成 nil
menukar kepingan kepada penunjuk tatasusunan0
进行比较:len(s) == 0
。无论它是 nil
切片还是非 nil
(ditambah pada bahasa dalam
). Menukar hirisan bukan kepada penunjuk tatasusunan akan menghasilkan penuding bukan , dan menukar hirisan
kepada penuding tatasusunan akan menghasilkan penudingUntuk mengetahui sama ada kepingan kosong, cuma bandingkan panjangnya dengan 0
: len(s) == 0
. Sama ada hirisan atau hirisan bukan reflect.SliceHeader
, tidak kira sama ada ia mempunyai kapasiti positif jika ia tidak mempunyai unsur, ia kosong.
s := make([]int, 0, 100) fmt.Println("Empty:", len(s) == 0, ", but capacity:", cap(s))Cetak (cuba di
Go Playgroundnil
切片,该结构将具有其零值,即其所有字段都将为零值,即:0
):
Empty: true , but capacity: 100
Lapisan bawahnil
切片的容量和长度等于 0
、Len
和 Cap
字段,则很可能是 0
,但 Data
指针可能不是。它不会,这就是它与 nil
type SliceHeader struct { Data uintptr Len int Cap int }🎜Untuk kepingan 🎜, struktur akan mempunyai nilai sifarnya, iaitu semua medannya akan mempunyai nilai sifar, iaitu:
0
. 🎜
🎜Jika kapasiti dan panjang kepingan bukan 🎜 adalah sama dengan medan 0
, Len
dan Cap
, maka kemungkinan besar 0 , tetapi penunjuk Data
mungkin tidak. Iatidak, begitulah bezanya dengan 🎜 hirisan. Ia akan menunjuk kepada tatasusunan asas bersaiz sifar. 🎜
🎜Perhatikan bahawa spesifikasi Go membolehkan nilai jenis berbeza dengan saiz 0 mempunyai alamat memori yang sama. 🎜Spesifikasi: Nota Sistem: Saiz dan Jaminan Penjajaran: 🎜🎜
让我们检查一下。为此,我们调用 unsafe
包的帮助,并“获取” reflect.SliceHeader
结构“视图” “我们的切片值:
var s1 []int s2 := []int{} s3 := make([]int, 0) fmt.Printf("s1 (addr: %p): %+8v\n", &s1, *(*reflect.SliceHeader)(unsafe.Pointer(&s1))) fmt.Printf("s2 (addr: %p): %+8v\n", &s2, *(*reflect.SliceHeader)(unsafe.Pointer(&s2))) fmt.Printf("s3 (addr: %p): %+8v\n", &s3, *(*reflect.SliceHeader)(unsafe.Pointer(&s3)))
输出(在 Go Playground 上尝试一下):
s1 (addr: 0x1040a130): {Data: 0 Len: 0 Cap: 0} s2 (addr: 0x1040a140): {Data: 1535812 Len: 0 Cap: 0} s3 (addr: 0x1040a150): {Data: 1535812 Len: 0 Cap: 0}
我们看到了什么?
nil
切片具有 0
数据指针s2
和 s3
切片确实具有相同的数据指针,共享/指向相同的 0 大小的内存值Atas ialah kandungan terperinci hirisan nil, hirisan bukan nol, hirisan kosong dalam bahasa Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!