對于所有數(shù)據(jù)而言,都是由bit組成(二進制數(shù)據(jù)),但是這些數(shù)據(jù)在頂層還是可以進一步區(qū)分,比如:整型、浮點數(shù)、比特數(shù)組、內(nèi)存地址等。這些數(shù)據(jù)可以組合成新的數(shù)據(jù)類型(例如map、slices等);也可以進一步表達更多的對象,如數(shù)據(jù)包、像素點等。
Go語言中的數(shù)據(jù)類型包括四類:基礎(chǔ)數(shù)據(jù)類型(整型、浮點數(shù)、復數(shù)、布爾型、字符串、常量)、復合類型(數(shù)組、Slice、Map、結(jié)構(gòu)體、JSON、文本和HTML模板)、引用類型和接口類型。
接下來將主要介紹基礎(chǔ)數(shù)據(jù)類型
一、整型:
Go語言提供了有符號和無符號(一般采用補碼形式體現(xiàn))兩類整型,其中,
有符號的包括:
int8(8bit、1字節(jié),-128 ~ 127)
int16(16bit、2字節(jié),-32768 ~ 32767)
int32(32bit、4字節(jié),-2147483648 ~ 2147483647)
int64(64bit、8字節(jié),-9223372036854775808 ~ 9223372036854775807)
無符號的包括:
uint8(8bit、1字節(jié),0 ~ 255,uint8和byte類型等價)
uint16(16bit、2字節(jié), 0 ~ 65535)
uint32(32bit、4字節(jié),0 ~ 4294967295)
uint64(64bit、8字節(jié),0 ~ 18446744073709551615)
一般而言,常用的有符號和無符號正數(shù)為int和uint,這兩個都是32或64bit(不同的CPU平臺會略有區(qū)別),但需要注意,int(uint)和int32(uint32)不是同一類型(雖然兩者都是32位),兩者需要做一個顯示的類型轉(zhuǎn)換操作。
這里還需要注意三種整型,byte、rune和uintptr:
btye:該類型是uint8類型的別名,等價于uint8,一般用于強調(diào)數(shù)值是一個原始數(shù)據(jù)而不是一個小的正數(shù),例如在代表ASCII碼時,就表示一個字符。
var ch byte = 'A'或 var ch byte = 65 或 var ch byte = '\x41' //(\x 總是緊跟著長度為 2 的 16 進制數(shù),所以\x41=65)
上述三種寫法均是相同的.
rune:代表一個UTF-8字符,當需要處理中文、日文或者其他復合字符時,則需要用到 rune 類型。rune 類型等價于 int32 類型。
uintptr:一種整數(shù)類型,沒有指定具體的大小,但是足夠容納一個指針的空間。其常用于底層編程。
二、浮點數(shù)
Go語言提供了兩種精度的浮點數(shù),float32和float64.一般浮點數(shù)的范圍極限可以在math包匯中找到,math.MaxFloat32表示float32能表示的最大數(shù),約為,math.MaxFloat64常量大約是
。它們分別能表示的最小值近似為
和
。
三、復數(shù)
Go語言提供了兩種精度的復數(shù)類型:complex64和complex128,分別對應float32和float64兩種浮點數(shù)精度。內(nèi)置的complex函數(shù)用于構(gòu)建復數(shù),內(nèi)建的real和imag函數(shù)分別返回復數(shù)的實部和虛部:
var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
fmt.Println(x*y) // "(-5+10i)"
fmt.Println(real(x*y)) // "-5"
fmt.Println(imag(x*y)) // "10"
復數(shù)也可以用==和!=進行相等比較。只有兩個復數(shù)的實部和虛部都相等的時候它們才是相等的(譯注:浮點數(shù)的相等比較是危險的,需要特別小心處理精度問題)。
四、運算符
在Go語言中,關(guān)于數(shù)值(包括正數(shù)、浮點數(shù)和復數(shù))的算術(shù)運算符、邏輯運算符和比較運算符,它們按照優(yōu)先級(5種優(yōu)先級)遞減的順序排列如下:
* / % << >> & &^
+ - | ^
== != < <= > >=
&&
||
在同一優(yōu)先級的二元運算符按照從左到右的順序結(jié)合。且取模預算符%只能用于整數(shù)間,取模運算符的符號與被取模數(shù)的符號一致,如-5%3和-5%-3的結(jié)果都是-2。
當進行算術(shù)運算時,如果計算結(jié)果溢出(尤其是+、*)時,超出高位的bit位部分會被丟棄。同時需要注意,運算符的兩端必須是相同類型的,否則會報出類型不匹配的錯誤。如:
var apples int32 = 1
var oranges int16 = 2
var compote int = apples + oranges //編譯錯誤 compile error
var compote = int(apples) + int(oranges) //正確寫法
比較運算符(==、!=、<、<=、>、>=)的結(jié)果為bool類型
位運算符包括以下幾種
& 位運算與 AND
| 位運算或 OR
^ 位運算異或 XOR
&^ 位清空 (AND NOT)
<< 左移
>> 右移
位運算符^作為二元運算符時表示按位異或(XOR),作為一元運算符時表示按位取反;位操作運算符&^用于按位置零(AND NOT):如果對應y中bit位為1的話, 表達式z = x &^ y結(jié)果z的對應的bit位為0,否則z對應的bit位等于x相應的bit位的值。
var x uint8 =1
fmt.Printf("%08b\n", x) //"00000001"
x = 1<<1 | 1<<5 //00000010|00100000
fmt.Printf("%08b\n", x) //"00100010"
var y uint8 = 1<<1 |1<<2
fmt.Printf("%08b\n", y) //"00000110"
fmt.Printf("%08b\n", x&y) // "00000010", the intersection {1}
fmt.Printf("%08b\n", x|y) // "00100110", the union {1, 2, 5}
fmt.Printf("%08b\n", x^y) // "00100100", the symmetric difference {2, 5}
fmt.Printf("%08b\n", x&^y) // "00100000", the difference {5}
fmt.Printf("%08b\n", x<<1) // "01000100", the set {2, 6}
fmt.Printf("%08b\n", x>>1) // "00010001", the set {0, 4}
fmt.Printf("%08b\n", ^x) //"11011101"
在進行移位操作時,左移操作<<(x<<n)可以等價于乘以,右移運算符>>(x>>2)可以等價于除以
五、fmt使用技巧
在使用fmt打印的時候,除了需要注意,可以用%d、%o或%x參數(shù)控制輸出的進制格式,就像下面的例子:
o := 0666
fmt.Printf("%d %[1]o %#[1]o\n", o) // "438 666 0666"
x := int64(0xdeadbeef)
fmt.Printf("%d %[1]x %#[1]x %#[1]X\n", x)
// Output:
// 3735928559 deadbeef 0xdeadbeef 0XDEADBEEF
fmt的Printf格式化字符串輸出還有兩個技巧:
1、當需要輸出多個相同的變量是可以用%[]替換,如%[1]表示Printf函數(shù)可以再次使用第一個操作數(shù)
2、%后的#副詞告訴Printf在用%o、%x或%X輸出時生成0、0x或0X前綴。
\\字符使用%c參數(shù)打印,或者是用%q參數(shù)打印帶單引號的字符:
ascii := 'a'
fmt.Printf("%d %[1]c %[1]q\n", ascii) // "97 a 'a'"