日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Golang——数据类型使用细节详解

發布時間:2025/3/15 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Golang——数据类型使用细节详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據類型:

計算機存儲設備最小信息單位是位(bit),最小的存儲單元是字節(byte)
占用字節的不同,所表示能存儲的數據長度不同

作用:

說明數據的數據的結構,便于后面定義變量、參數傳遞等

默認值:

類型默認值
整型0
浮點型0.0
字符串""
布爾類型false

數據類型說明:

類型有無符號名稱占用字節說明
bool布爾類型1只有true或false,默認是false
byte字節型1等價于uint8,當要存儲字符的時候可以byte
rune字符類型4專用于存儲unicode編碼,等價于uint32
int整型4或832位系統4個字節 64位系統8個字節int占用多大取決于操作系統
uint整型4或832位系統4個字節 64位系統8個字節
int8整型1-128 ~ 127
int16整型2-32768 ~ 32767
int32整型4-2147483648 到 2147483647
int64整型80 到 18446744073709551615(1844京)
uint8整型10 ~ 255
uint16整型20 ~ 65535
uint32整型40 到 4294967295(42億)
uint64整型8-9223372036854775808到 9223372036854775807
float32浮點型4小數位精確到7位
float64浮點型8小數位精確到15位
complex64復數類型8
complex128復數類型16
uintptr整型4或8?以存儲指針的uint32或uint64整數
string字符串utf-8字符串

有符號和無符號的區別

有符號的,長度第一位會存數據類型,剩余的長度才是數據。無符號的全部都可以存數據。前面有u就是無符號,沒有u就是有符號

有符號和無符號如何選擇:

如果只存整數就使用無符號的,因為范圍更大,如果存的有負數就用有符號的。
能用小的就不要選擇大的,比如年齡就用byte(0 ~ 255)

如何查看變量的數據類型:

fmt.Printf("%T", 變量名)// 輸出不換行,可以指定輸出的變量類型

如何查看數據類型占用的字節大小:

fmt.Printf("%d", unsafe.Sizeof(num))// unsafe.Sizeof(num):返回指定變量占用的字節數

基本數據類型和引用類型區別:

基本數據類型:int、float、bool、string、數組、結構體
引用類型:指針、切片、map、管道、接口

區別:

基本數據類型的變量是直接存數據的,通常在棧中分配的
引用數據類型的變量是先存一個內存地址,這個變量分配的空間才是存數據的,通常在堆中分配的。當沒有引用變量的時候,會由GC回收變成垃圾

整型:

演示:

func test() {var age uint = -10println(age) // 報錯,不支持負數 }

浮點類型:

  • 關于數學運算的包里默認都是用的float64,日常使用也盡量使用float64的就行了
  • 浮點數可能會造成精度損失,64位的要比32位的更精準

演示:

func test02() {var sum float64 = 123.456789sum2 := 123.456789 // 如果使用的是自動推導類型,默認就是float64類型的fmt.Printf("%f\n", sum) //123.456789fmt.Printf("%.2f\n", sum) // 使用".數字"可以保留小數位數并四舍五入 123.46fmt.Printf("%T", sum2) // float64 %T可以打印出變量的類型 }

布爾類型:

  • 布爾類型也叫bool類型,布爾類型的取值要么是true,要么是false
  • bool適合做邏輯運算,一般用在流程控制語句里
  • 使用bool關鍵字進行定義,默認值為false
var b bool = truefmt.Println(b)

字符類型:

  • Golang沒有字符類型,類似java的char,如果要存儲單個字符,一般使用byte保存。
  • 字符串本質是一串固定長度字符連接起來的字符序列,但是在Golang里是由單個字節連接起來的
  • 如果需要保存的變量值大于255時使用byte會溢出,可以使用int代替byte保存數據
  • Go語言的字符使用的是UTF-8編碼標識Unicode文本,所以Go統一使用了UTF-8沒有亂碼的問題出
  • 字符的本質也是一個整數,直接輸出的時候是按照對應的UTF-8編碼的碼值運算的,所以字符可以參與運算。
  • 字符變量賦值后,通過c%可以打印出該數字對應的unicode字符
  • 用單引號引起來的字符,單引號里只能有一個字符,數據類型為byte
    點擊查看ASCLL碼表

演示:

//b := 'b'var b byte = 'a'fmt.Println(b) // 打印結果不是b,是98,fmt.Printf("%c", b) // c%可以打印出該數字對應的unicode字符var z int = 'a'fmt.Println(z)

字符串類型:

  • 字符串本質是一串固定長度字符連接起來的字符序列,但是在Golang里是由單個字節連接起來的
  • 字符串中有一個隱藏的結束標志\0
  • Go語言默認為UTF-8編碼存儲Unicode字符,所以Go統一使用了UTF-8沒有亂碼的問題出現
  • 字符串一旦賦值就不能修改了,字符串是不可變的
  • 雙引號格式會識別字符串里的轉義字符
  • 反引號以字符串的原生形式輸出,在反引號里的內容全部都是普通文本,包括換行和特殊字符,可以實現防止攻擊、輸入源代碼的效果
  • 默認空字符串不是nil,而是""
//name := "itzhuzhu"var name string = "itzhuzhu"fmt.Printf("%T\n", name) // 打印字符串的數據類型fmt.Println(name) // 打印字符串的數據值fmt.Println(len(name)) // 打印字符串的長度,如果是中文的話,一個中文是3個字節// 使用反引號會原樣輸出,編譯器不會解析原始字符串內的數據str := `func save() {var age int = 10var a int = 1var b int = avar name stringfmt.Println(age)fmt.Println(name)fmt.Println(a, b)} `str2 := "嘻嘻"str += "可以再次拼接字符串,也可以和其它字符串變量一起拼接" + str2fmt.Println(str)

在golang中做字符串拼接的時候如果需要換行,需要把加號放在上一行,否則會報錯

允許以索引號訪問字節數組(并非字符),但不能獲取數組元素地址

func main() {s := "abc"println(s[1])println(&s[1]) // 錯誤: cannot take the address of s[1] }

以切片語法(起始和結束索引號)返回子串時,其內部依舊指向原字節數組

func main() {s := "abcdefg"s1 := s[:3] // 從頭開始,僅指定結束索引位置s2 := s[1:4] // 指定開始和結束位置,返回[start, end)s3 := s[2:] // 指定開始位置,返回后面全部內容println(s1, s2, s3)// reflect.StringHeader 和 string 頭結構相同。// unsafe.Pointer用于指針類型轉換。fmt.Printf("%#v\n", (*reflect.StringHeader)(unsafe.Pointer(&s)))fmt.Printf("%#v\n", (*reflect.StringHeader)(unsafe.Pointer(&s1))) }

StringHeader源碼

type StringHeader struct {Data uintptr // 存方指針,指向的是原數組Len int // 字符串的長度 }

使用for遍歷字符串時,分byte和rune兩種方式

func main() {s := "itzhuzhu"for i := 0; i < len(s); i++ { // bytefmt.Printf("%d: [%c]\n", i, s[i])}fmt.Println("-------------------")for i, c := range s { // rune,返回數組索引號,以及Unicode字符fmt.Printf("%d: [%c]\n", i, c)} }

用加法操作符拼接字符串時,每次都需重新分配內存。如此,在構建“超大”字符串時,性能就顯得極差

func test() string {var s stringfor i := 0; i < 1000; i++ {s += "a"}return s } func BenchmarkTest(b *testing.B) {for i := 0; i < b.N; i++ {test()} }

改進方法就是預先分配足夠的內存空間。常用方法是用strings.Join函數,它會統計所有參數長度,并一次性完成內存分配操作

func test() string {s := make([]string, 1000) // 分配足夠的內存,避免中途擴張底層數組for i := 0; i < 1000; i++ {s[i] = "a"}return strings.Join(s, "") }

改進后的算法有巨大提升。還有bytes.Buffer也可完成相同操作,且性能相當

func test() string {var b bytes.Bufferb.Grow(1000) // 分配足夠的內存,避免中途擴張底層數組for i := 0; i < 1000; i++ {b.WriteString("a")}return b.String() }

對于數量較少的字符串格式化拼接,可使用fmt.Sprintf、text/template等方法

引用類型:

  • Go的引用類型特指slice、map、channel這三種,相比數字、數組等類型,引用類型擁有更復雜的存儲結構。除分配內存外,它們還需初始化一系列屬性,諸如指針、長度,甚至包括哈希分布、數據隊列等。
  • 內置函數new依指定類型數據長度分配內存,返回指針。而引用類型則必須使用make有 數創建,編譯器將make轉換為目標類型專用創建函數(或指令),以完成內存分配和屬性初始化。

rune:

類型rune專門用來存儲Unicode Code Point,它是int32的別名,相當于UCS-4/UTF-32 編碼格式。使用單引號的字面量,其默認類型就是rune

除[ ]rune外,還可直接在rune、byte、string間進行轉換

func main() {r := '哈's := string(r) // rune to string b := byte(r) // rune to byte s2 := string(b) // byte to string r2 := rune(b) // byte to rune fmt.Println(s, b, s2, r2) }

總結

以上是生活随笔為你收集整理的Golang——数据类型使用细节详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。