go語言中基本數據類型及應用實例分析
這篇“go語言中基本數據類型及應用實例分析”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“go語言中基本數據類型及應用實例分析”文章吧。
整數
按位長度分度分為:8位,16位,32位,64位。
對應有符號整數:int8,int16,int32,int64。
對應無符號整數:uint8,uint16,uint32,uint64。
計算最大數和最小數規則:
有符號整數:由于有符號,因此位數的最高位被用來存儲符號,其他為存儲數據值,所以對于
n
位數來說,取值范圍是:-2^(n-1)^~2^(n-1)^-1,對應int8來說,就是 -127 ~ 127。無符號正數:不需要用最高位記錄符號,全部位數表示數字。取值范圍是:0 ~ 2^n^-1。對于int8來說,就是0 ~ 255。
特殊的整數類型
int
和uint
以及uintptr
。
int
和uint
根據特定的平臺,其大小與原生的整數相同或者是該平臺上運算效率最高的值。要么同時是64位,要么同時是32位,但也不能假定他們就是64位或者32位的整型。即使在一樣的硬件下,不同編譯器也有可能選用不同的大小。
至于uintptr
,它的大小并不明確。但它肯定足夠容納一個指針的大小。常用于底層編程。
雖然int
、uint
的長度可能與int32
、int64
、..
其他整型相同但是他們是不同的類型。
如果想確定int
和uint
的大小
fmt.Println(runtime.GOARCH) //?看看CPU型號 fmt.Println(strconv.IntSize) //?這才是int的大小,上面只是提供一個對照
溢出
不論是有符號數還是無符號數,若計算結果所需的位超出類型的范圍,就稱為溢出。溢出的高位會被無提示地拋棄。
var?i?int8?=?-128 fmt.Println(i-1) //?127 var?i2?int8?=?127 fmt.Println(i2+1) //?-128 var?u?uint8?=?0 fmt.Println(u-1) //?255 var?u2?uint8?=?255 fmt.Println(u2+1) //?0
浮點數
float32
、float64
。遵循IEEE 754
標準。
math.MaxFloat32
給出了float32
類型的最大值:3.4028234663852886e+38
。
math.MaxFloat64
則是float64
類型的最大值:1.7976931348623157e+308
。
浮點數可以用來表示小數。
十進制下,float32
有效位大約是6位。float64
有效位大約是15位。
浮點數的打印可以使用:
%g
,保留足夠的精度顯示%e
,使用指數形式顯示%f
,使用無指數形式顯示
f?:=?2.71828 fmt.Printf("%g,?%[1]e,?%[1]f?\n",?f) //?2.71828,?2.718280e+00,?2.718280
復數
complex64
、complex128
?,二者分別由float32
和float64
組成。
使用real
函數提取復數的實部,使用imag
函數提取復數的虛部。
浮點數或者整數后面加i
就會變成一個虛數,且它的實部為0
。
x?:=?1+2i y?:=?3+4i
布爾值
bool
類型就是布爾值,有true
(真)和false
(假)兩個值。
布爾值無法隱式轉換成數值,數值也不能轉成布爾值。
它的零值是false
。
一元操作符!
表示邏輯取反。!true
表示false
。
字符串
string
表示字符串。它是不可變的字節序列。Go中的字符串內部實現用UTF-8
編碼。
字符串的“長度”與遍歷字符串的做法
字符串的“長度”
對字符串調用len
函數,獲取到的不是字符串的長度(字符的個數),而是字符串的字節數(字節切片的長度)。
如下,盡管字符個數只有6,但字節長度len(s)
卻有18,這是因為中文字符以UTF-8
存儲,通常包含3~4個字節。
s?:=?"中文字節數多" fmt.Println("len:?",?len(s)) //?len:??18
對字符串使用下標索引操作,會返回對應索引的字節,而不是字符。
s?:=?"中文字節數多" fmt.Println("len:?",?len(s)) //?len:??18 for?i?:=0;?i?<?len(s);?i++?{ ????fmt.Printf("%d,?%[1]c,?%[1]T\n",s[i]) }
對應的輸出如下:
len: 18
228, ä, uint8
184, ¸, uint8
173, ­, uint8
230, æ, uint8
150, ?, uint8
135, ?, uint8
229, å, uint8
173, ­, uint8
151, ?, uint8
232, è, uint8
138, ?, uint8
130, ?, uint8
230, æ, uint8
149, ?, uint8
176, °, uint8
229, å, uint8
164, ¤, uint8
154, ?, uint8
因此不要隨便亂用字符串的下標操作,否則可能獲得有意想不到的結果。
遍歷字符串
由上面的下標操作可以看出,對字符串的下標索引操作會獲得單個字節而不是字符,假如現在我們想處理的是UTF-8
解碼的字符的話,有兩種方式,基本思路都是處理成rune
類型:
第一種,用UTF-8
解碼器顯式處理這些字符,unicode/utf8
包示例。
utf8.RuneCountInString(s)
返回字符串轉為rune
后的個數,Go使用rune
代表一個UTF-8
字符。
utf8.utf8.DecodeRuneInString(s[i:])
處理當前字符串,并算出下一個rune
以及它所占的字節數。
s?:=?"What??中文字節數多" runeCount?:=?utf8.RuneCountInString(s) fmt.Println("runeCount:",?runeCount) //?runeCount:?12 for?i:=?0;?i<len(s);?{ r,?size:=?utf8.DecodeRuneInString(s[i:]) fmt.Printf("i:?%d,?r:%q,?type:%T?\n",?i,?r,?r) i?+=?size }
輸出如下:
runeCount: 12
i: 0, r:'W', type:int32
i: 1, r:'h', type:int32
i: 2, r:'a', type:int32
i: 3, r:'t', type:int32
i: 4, r:'?', type:int32
i: 5, r:' ', type:int32
i: 6, r:'中', type:int32
i: 9, r:'文', type:int32
i: 12, r:'字', type:int32
i: 15, r:'節', type:int32
i: 18, r:'數', type:int32
i: 21, r:'多', type:int32
第二種,用range
循環,Go會隱式的進行UTF-8
解碼。
注意,這里的i
,指的是字節的下標,而不是字符的下標。
s?:=?"What??中文字節數多" for?i,?r?:=?range?s?{ ????fmt.Printf("i:?%d,?rune:?%q,?type:?%T?\n",?i,?r,?r) }
輸出如下:
i: 0, rune: 'W', type: int32
i: 1, rune: 'h', type: int32
i: 2, rune: 'a', type: int32
i: 3, rune: 't', type: int32
i: 4, rune: '?', type: int32
i: 5, rune: ' ', type: int32
i: 6, rune: '中', type: int32
i: 9, rune: '文', type: int32
i: 12, rune: '字', type: int32
i: 15, rune: '節', type: int32
i: 18, rune: '數', type: int32
i: 21, rune: '多', type: int32
Rune與Byte(字節)
int32
的別名是rune
,天然適合存儲單個文字符號,為Go所采用的。
rune
類型值代表一個UTF-8
字符。以字節(byte)為單位對Unicode
碼點作變長編碼?,F在計算機都用UTF-8
來表示單個字符。
字符串的是由“字符”組成的,字符用單引號’
包裹起來,如:
var?b?=?'h' c?:=?'沖' fmt.Printf("%d,?%q?\n",?b,?b) //?104,?'h' fmt.Printf("%d,?%q?\n",?c,?c) //?20914,?'沖'
字節,byte
類型,底層類型是uint8
,由8個bit
組成,它可以代表一個ASCII
碼。ASCII
碼是滿足早期計算機的使用的,它用7位表示128個“字符”(ASCII字符):大小寫英文字母、數字、標點符號和設備控制符。
字符串與字節slice的轉換
字符串底層是一個字節數組,所以可以和[]byte
類型互換。
s?:=?"abc" b?:=?[]byte(s) s2?:=?string(b)
概念上,[]byte(s)
轉換操作會分配新的字節數組,拷貝填入s
含有的字節,并生成一個slice
的引用,指向整個數組。反之,用string(b)
也會產生一份副本而不是操作真正的b
,以此保證上面s2
不變。
字符串不可變
字符串是不可變的,表現在其字符串值不可修改。平時我們看到的字符串修改操作、拼接操作并不改變原有的字符串值,而是將操作后生成新的字符串值賦予原來的變量。
s?:=?"left?foot" t?:=?s s?+=?",?right?foot"
盡管字符串創建后,它底層的字節slice不可變,但是普通的字節slice
是可以隨意改變的。
var?a?=?[]byte{'h',?'e',?'l',?'l',?'o'} fmt.Printf("%p,?%[1]q?\n",?a) //?0xc00000a098,?"hello" a[4]?=?'?' fmt.Printf("%p,?%[1]q?\n",?a) //?0xc00000a098,?"hell?"
由于字符串的不可變以及避免頻繁的操作字符串而導致的多次內存分配和復制,可以使用bytes.Buffer
類型。
見GOPL的一個例子:
func?intsToString(values?[]int)?string?{ var?buf?bytes.Buffer buf.WriteByte('[') for?i,?v?:=?range?values?{ if?i?>?0?{ buf.WriteString(",") } fmt.Fprintf(&buf,?"%d",?v) } buf.WriteByte(']') return?buf.String() } func?main()?{ fmt.Println(intsToString([]int{1,?2,?3}))?//?[1,2,3] }
追加ASCII
字符可以用writeByte
,追加UTF-8
編碼的文字符號,最好用WriteRune
方法。
基本類型的值都是可比較的
基本類型的值都是可比較的,如布爾值、數值、字符串等。
數值的類型轉換
很多整型—整型的轉換不會引起值的變化,僅告知編譯器如何解讀這么值。但縮減大小的類型轉換,以及整型與浮點型的相互轉換,會因此值的改變或者損失精度。
浮點型轉整型會舍棄小數部分并向0取整。
var?f?=?3.526 i?:=?int(f) fmt.Printf("f:?%v,?i:?%v?\n",?f,?i)?//?f:?3.526,?i:?3? var?i16?=?int16(555) var?i8?=?int8(i16) fmt.Printf("i16:?%v,?i8:?%v?\n",?i16,?i8)?//?i16:?555,?i8:?43
運算符
運算符降序排列:
*? /? %? <<? >>? &? &^ +? -? |? ^ == != < <= > >= && ||
二元運算符分為五大優先級。同級別的運算符滿足左結合律,可以用圓括號指定次序。
常量
常量是一種表達式,保證在編譯階段就計算出對應的值。所有常量本質上都屬于基本類型:布爾型、字符串或者數字。
常量自編譯后,其值恒定不變。
type?Integer?int const?I?Integer?=?10 const?S?string?=?"important_secret" const?( NUM1?=?1 NUM2?=?2 NUM3 NUM4?=?5.5 STR1?=?"STR1" ) func?main()?{ fmt.Printf("I:?%v?\n",?I) fmt.Printf("S:?%v?\n",?S) fmt.Printf("NUM1:?%v?\n",?NUM1) fmt.Printf("NUM2:?%v?\n",?NUM2) fmt.Printf("NUM3:?%v?\n",?NUM3) fmt.Printf("NUM4:?%v?\n",?NUM4) fmt.Printf("STR1:?%v?\n",?STR1) }
輸出如下:
I: 10
S: important_secret
NUM1: 1
NUM2: 2
NUM3: 2
NUM4: 5.5
STR1: STR1
以上就是關于“go語言中基本數據類型及應用實例分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注蝸牛博客行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:niceseo99@gmail.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。
評論