夯實Golang基礎之數據類型梳理匯總
類型匯總
Go 語言中,主要分為值類型主要分為三部分: 整型、浮點型和其他類型。
// 整型 int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr // 浮點型、復數 float32 float64 complex128 complex64 // 其他類型 bool byte rune string error
整型
Go語言同時提供了有符號和無符號類型的整數運算。
int int8 int16 int32 有符合和無符號類型
這里有int8、int16、int32和int64四種截然不同大小的有符號整數類型,分別對應8、16、32、64bit大小的有符號整數,與此對應的是uint8、uint16、uint32和uint64四種無符號整數類型。
這里還有兩種一般對應特定CPU平臺機器字大小的有符號和無符號整數int和uint;其中int是應用最廣泛的數值類型。這兩種類型都有同樣的大小,32或64bit,但是我們不能對此做任何的假設;因為不同的編譯器即使在相同的硬件平臺上可能產生不同的大小。
uintptr 類型
uintptr 是一種無符號的整數類型 ,沒有指定具體的bit大小但是足以容納指針。uintptr 類型只有在底層編程時才需要,特別是Go語言和C語言函數庫或操作系統接口相交互的地方。
不管它們的具體大小,int、uint 和 uintptr 是不同類型的兄弟類型。其中int和int32也是不同的類型,即使int的大小也是32bit,在需要將int當作int32類型的地方需要一個顯式的類型轉換操作,反之亦然。
類型值范圍
類型名稱 | 大小 | 描述 |
---|---|---|
int | 8 字節(jié) | int的大小是和操作系統位數相關的,如果是32位操作系統,int類型的大小是4字節(jié);如果是64位操作系統,int類型的大小就是8個字節(jié) |
int8 | 1 字節(jié) | 無符號整數的所有bit位都用于表示非負數,值域是0到$2^n-1$。例如,int8類型整數的值域是從-128到127,而uint8類型整數的值域是從0到255。 |
int16 | 2 字節(jié) | 有符號int16類型整數值域是從 -32768 ~ 32767,而無符號uint16類型整數值域是從 0 ~ 65535 |
int32 | 4 字節(jié) | 有符號int32類型整數值域是從 -2147483648 ~ 2147483647,而無符號uint32類型整數值域是從 0 ~ 4294967295 |
int64 | 8 字節(jié) | 有符號int64類型整數值域是從 -9223372036854775808 ~ 9223372036854775807,而無符號uint64類型整數值域是從 0 ~ 18446744073709551615 |
uintptr | 長度4或8字節(jié) | 存儲指針的uint32 或 uint64整數 |
取值范圍示例
package main import ( "fmt" "math" "unsafe" ) func main() { fmt.Println("各int類型的大小: ") var i1 int = 1 var i2 int8 = 2 var i3 int16 = 3 var i4 int32 = 4 var i5 int64 = 5 var i6 uint64 = 6 fmt.Printf("int : %v\n", unsafe.Sizeof(i1)) fmt.Printf("int8 : %v\n", unsafe.Sizeof(i2)) fmt.Printf("int16 : %v\n", unsafe.Sizeof(i3)) fmt.Printf("int32 : %v\n", unsafe.Sizeof(i4)) fmt.Printf("int64 : %v\n", unsafe.Sizeof(i5)) fmt.Printf("uint64: %v\n", unsafe.Sizeof(i6)) // 輸出各int類型的取值范圍 fmt.Println("int8:", math.MinInt8, "~", math.MaxInt8) fmt.Println("int16:", math.MinInt16, "~", math.MaxInt16) fmt.Println("int32:", math.MinInt32, "~", math.MaxInt32) fmt.Println("int64:", math.MinInt64, "~", math.MaxInt64) fmt.Println() // n是自動推導類型 n := 1234567890 fmt.Printf("n := 1234567890 的默認類型為: %T\n", n) fmt.Printf("int類型的字節(jié)數為: %v\n\n", unsafe.Sizeof(n)) // 初始化一個32位整型值 var a int32 = 987654321 fmt.Println("var a int32 = 987654321") // 輸出變量的十六進制形式和十進制 fmt.Printf("int32: 十六進制為0x%x, 十進制為%d\n", a, a) // 將a轉換為int8類型, 發(fā)生數值截斷 b := int8(a) fmt.Printf("int8: 十六進制0x%x, 十進制為%d\n", b, b) // 將a轉換為int16類型, 發(fā)生數值截斷 c := int16(a) fmt.Printf("int16: 十六進制為0x%x, 十進制%d\n", c, c) // 將a轉換為int64類型 d := int64(a) fmt.Printf("int64: 十六進制為0x%x, 十進制%d\n", d, d) }
浮點型
浮點數類型的取值范圍可以從很微小到很巨大。浮點數的范圍極限值可以在math包找到。常量math.MaxFloat32表示float32能表示的最大數值,大約是 3.4e38
;對應的 math.MaxFloat64 常量大約是1.8e308
。它們分別能表示的最小值近似為1.4e-45
和4.9e-324
。
上述值,以科學計數法表示
列如:e38 就是小數點向右移動38位
? e-35 就是小數點向左移動35位
float32、float64 類型
一個float32類型的浮點數可以提供大約6個十進制數的精度,而float64則可以提供約15個十進制數的精度;通常應該優(yōu)先使用float64類型,因為float32類型的累計計算誤差很容易擴散,并且float32能精確表示的正整數并不是很大(譯注:因為float32的有效bit位只有23個,其它的bit位用于指數和符號;當整數大于23bit能表達的范圍時,float32的表示將出現誤差)
complex64、complex128 類型
Go語言提供了兩種精度的復數類型:complex64 和 complex128,分別對應 float32 和 float64 兩種浮點數精度。
實際上,complex64類型的值會由兩個float32類型的值分別表示復數的實數部分和虛數部分。 complex128類型的值會由兩個float64類型的值分別表示復數的實數部分和虛數部分。
復數類型的值一般由浮點數表示的實數部分、加號“+”、浮點數表示的虛數部分,以及小寫字母“i”組成。比如, 3.7E+1 + 5.98E-2i
。正因為復數類型的值由兩個浮點數類型值組成,所以其表示法的規(guī)則自然需遵從浮點數類型的值表示法的相關規(guī)則。
舉例,內置的complex函數用于構建復數,內建的real和imag函數分別返回復數的實部和虛部:
var x complex128 = complex(1, 2)
類型值范圍
類型名稱 | 大小 | 描述 |
---|---|---|
float32 | 4 字節(jié) | 單精度類型,占據4個字節(jié)byte,32個二進制位bit |
float64 | 8 字節(jié) | 雙精度類型比單精度類型更能精確地表示一個小數,但是占用的內存空間也比較大。 |
complex64 | 8 字節(jié) | 包含兩個float32類型表示復數 |
complex128 | 16 字節(jié) | 包含兩個float64類型表示復數 |
布爾型
布爾類型的值只有兩種:true
和 false
。if和for語句的條件部分都是布爾類型的值,并且==和<等比較操作也會產生布爾型的值。一元操作符!
對應邏輯非操作,因此!true
的值為false
,更羅嗦的說法是(!true==false)==true
,雖然表達方式不一樣,不過我們一般會采用簡潔的布爾表達式,就像用x來表示x==true
。
使用
數字到布爾類型的轉換
func itob(i int) bool { return i != 0 }
rune 類型
rune 類型是和 int32 類型等價,在所有方面都等同于 int32
,按照約定,它用于區(qū)分字符值和整數值。
常用來處理 unicode 或 utf-8 字符,通常用于表示一個Unicode碼點,這兩個名稱可以互換使用。
說的通俗一點就是 rune
一個值代表的就是一個 Unicode
字符,它的最大特點就是可變長。它可以使用 1 - 4
個字節(jié)表示一個字符,根據字符的不同變換長度。所以使用int32
類型范圍就可以完美適配。 單個中文占 2 個字節(jié),單個英文占 2 個字節(jié)。
因為 Go 語言中字符串編碼為 UTF-8
,英文占 1
個字節(jié),中文占 3
個字節(jié)。 占用空間相比之下會更大
使用
計算中文字符
package main import ( "fmt" ) func main() { var data = "帽兒山的槍手" fmt.Println("data length", len(data)) fmt.Println("data word length", len([]rune(data))) }
程序輸出
data length 18
data word length 6
具體原因
len()
函數是用來獲取字符串的字節(jié)長度
在 utf-8
編碼中,英文占 1
個字節(jié),中文占 3
個字節(jié)
rune
一個值代表的就是一個 Unicode
字符,所以求 rune
切片的長度就是字符個數。
byte 類型
同樣 byte也是uint8類型 的等價類型,byte類型一般用于強調數值是一個原始的數據而不是一個小的整數。
使用
字符串和字節(jié)slice之間可以相互轉換
s := "abc" b := []byte(s) s2 := string(b)
string 類型
string 是 8 位字節(jié)的集合,通常但不一定代表UTF-8
編碼的文本。string
可以為空,但不能為nil
。
字符串是一個不可改變的字節(jié)序列。 字符串可以包含任意的數據,包括byte值0, 但是通常是用來包含人類刻度的文本。文本字符串通常被解釋為采用UTF8編碼的Unicode碼點(rune)序列。
字符串底層是一個byte數組,所以可以和[]byte類型相互轉換。字符串是不能修改字符串是由byte字節(jié)組成,所以字符串的長度是byte字節(jié)的長度。
Go語言源文件總是用UTF8編碼, 并且Go語言的文本字符串也是以UTF8編碼的方式處理,因此我們可以將Unicode碼點也寫到字符串面值中。
使用
拼接字符串
package main import ( "fmt" ) func main(){ // %d 表示整形數字, %s 表示字符串 var stockcode int = 123 var enddate string = "2022-01-18" var url string = "Code=%d&endDate=%s" var target_url = fmt.Sprintf(url, stockcode, enddate) fmt.Println(target_url) }
error 類型
error 類型是 Go 語言的一種內置類型,使用的時候不用特定去import,它本質上是一個接口。
type error interface{ Error() string //Error()是每一個訂制的error對象需要填充的錯誤消息,可以理解成是一個字段Error }
使用
封裝自定義錯誤類型
package main import ( "fmt" "errors" ) type Error struct { err error } func (e Error) MyError() string { return e.err.Error() } func main() { err := Error { errors.New("test error"), } fmt.Println(err.MyError()) }
以上就是夯實Golang基礎之數據類型梳理匯總的詳細內容,更多關于Golang數據類型的資料請關注腳本之家其它相關文章!