【golang】unsafe.Sizeof淺析


【golang】unsafe.Sizeof淺析
博主也是正在學習golang,在學習過程中遇到了SizeOf的問題。我原先以為,golang中的sizeof和c的sizeof差不多,但是當我開始使用的時候,才發現了許多奇怪的問題

slice := []int{1,2,3}
fmt.Println(unsafe.Sizeof(slice)) //24
1
2
上面聲明了一個切片,然后打印出sizeof的值為24,但是不管slice里的元素為多少,sizeof返回的數據都是24。

然后在官方文檔上找到一句話

Sizeof takes an expression x of any type and returns the size in bytes of a hypothetical variable v as if v was declared via var v = x. The size does not include any memory possibly referenced by x. For instance, if x is a slice, Sizeof returns the size of the slice descriptor, not the size of the memory referenced by the slice.

最后一句

if x is a slice, Sizeof returns the size of the slice descriptor, not the size of the memory referenced by the slice.

如果x為一個切片,sizeof返回的大小是切片的描述符,而不是切片所指向的內存的大小。

那么這里如果換成一個數組呢?而不是一個切片

arr := [...]int{1,2,3,4,5}
fmt.Println(unsafe.Sizeof(arr)) //40
arr2 := [...]int{1,2,3,4,5,6}
fmt.Println(unsafe.Sizeof(arr)) //48
1
2
3
4
可以看到sizeof(arr)的值是在隨着arr的元素的個數的增加而增加

這是為啥?

sizeof總是在編譯期就進行求值,而不是在運行時,這意味着,sizeof的返回值可以賦值給常量

在編譯期求值,還意味着可以獲得數組所占的內存大小,因為數組總是在編譯期就指明自己的容量,並且在以后都是不可變的

再來看一個字符串的例子

str := "hello"
fmt.Println(unsafe.Sizeof(str)) //16
1
2
不論字符串的len有多大,sizeof始終返回16,這是為啥,字符串不是也是不可變的嗎?實際上字符串類型對應一個結構體,該結構體有兩個域,第一個域是指向該字符串的指針,第二個域是字符串的長度,每個域占8個字節,但是並不包含指針指向的字符串的內容,這也就是為什么sizeof始終返回的是16

總結
unsafe包的官方文檔這樣說道

導入unsafe的軟件包可能不可移植,並且不受Go 1兼容性指南的保護。

而Go聖經里這樣說

雖然這幾個函數在不安全的unsafe包,但是這幾個函數調用並不是真的不安全,特別在需要優化內存空間時它們返回的結果對於理解原生的內存布局很有幫助。

雖然unsafe這個名字聽起來很危險,但是既然go官方提供了這個包,那我們就可以在任何必要的時候,去根據情況取舍
————————————————
版權聲明:本文為CSDN博主「小辣抓」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/HaoDaWang/java/article/details/80005072


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM