Go 語言是一種靜態類型的編程語言,在 Go 編程語言中,數據類型用於聲明函數和變量。數據類型的出現是為了把數據分成所需內存大小不同的數據,編程的時候需要用大數據的時候才需要申請大內存,就可以充分利用內存。編譯器在進行編譯的時候,就要知道每個值的類型,這樣編譯器就知道要為這個值分配多少內存,並且知道這段分配的內存表示什么。
基本數據類型說明
類型 | 描述 |
---|---|
uint | 32位或64位 |
uint8 | 無符號 8 位整型 (0 到 255) |
uint16 | 無符號 16 位整型 (0 到 65535) |
uint32 | 無符號 32 位整型 (0 到 4294967295) |
uint64 | 無符號 64 位整型 (0 到 18446744073709551615) |
int | 32位或64位 |
int8 | 有符號 8 位整型 (-128 到 127) |
int16 | 有符號 16 位整型 (-32768 到 32767) |
int32 | 有符號 32 位整型 (-2147483648 到 2147483647) |
int64 | 有符號 64 位整型 (-9223372036854775808 到 9223372036854775807) |
byte | uint8的別名(type byte = uint8) |
rune | int32的別名(type rune = int32),表示一個unicode碼 |
uintptr | 無符號整型,用於存放一個指針是一種無符號的整數類型,沒有指定具體的bit大小但是足以容納指針。 uintptr類型只有在底層編程是才需要,特別是Go語言和C語言函數庫或操作系統接口相交互的地方。 |
float32 | IEEE-754 32位浮點型數 |
float64 | IEEE-754 64位浮點型數 |
complex64 | 32 位實數和虛數 |
complex128 | 64 位實數和虛數 |
整型
整型數據分為兩類,有符號
和無符號
兩種類型
有符號: int, int8, int16, int32, int64
無符號: uint, uint8, uint16, uint32, uint64, byte
不同位數的整型區別在於能保存整型數字范圍的大小;
有符號類型可以存儲任何整數,無符號類型只能存儲自然數
int和uint的大小和系統有關,32位系統表示int32和uint32,如果是64位系統則表示int64和uint64
byte與uint8類似,一般用來存儲單個字符
在保證程序正確運行下,盡量使用占用空間小的數據類型
fmt.Printf("%T", var_name)輸出變量類型
unsafe.Sizeof(var_name)查看變量占用字節
浮點型
浮點型也就是小數類型,可以存放小數。比如6.6,-12.34
-
關於浮點數在機器中存放形式的簡單說明,浮點數=符號位+指數位+尾數位
-
尾數部分可能丟失,造成精度損失。-123.0000901
package main import "fmt" func main() { var num1 float32 = -123.0000901 var num2 float64 = -123.0000901 fmt.Println("num1 = ", num1, "num2 = ", num2); }
說明:float64的精度要比float32的要准確
說明:如果我們要保存一個精度高的數,則應該選擇float64
-
浮點型的存儲分為三部分:符號位+指數位+尾數位,在存儲過程中,精度會有丟失
-
golang的浮點型默認為float64類型
-
通常情況下,應該使用float64,因為它比float32更精確
-
0.123可以簡寫成.123,也支持科學計數法表示:5.1234e2 等價於512.34
字符
Golang中沒有專門的字符類型,如果要存儲單個字符(字母),一般使用byte來保存。
字符串就是一串固定長度的字符連接起來的字符序列。Go的字符串是由單個字節連接起來的,也就是說對於傳統的字符串是由字符組成的,而Go的字符串不同,它是由字節組成的。
- 字符只能被單引號包裹,不能用雙引號,雙引號包裹的是字符串
- 當我們直接輸出type值時,就是輸出了對應字符的ASCII碼值
- 當我們希望輸出對應字符,需要使用格式化輸出
- Go語言的字符使用UTF-8編碼,英文字母占一個字符,漢字占三個字符
- 在Go中,字符的本質是一個整數,直接輸出時,是該字符對應的UTF-8編碼的碼值。
- 可以直接給某個變量賦一個數字,然后按格式化輸出時%c,會輸出該數字對應的unicode字符
- 字符類型是可以運算的,相當於一個整數,因為它們都有對應的unicode碼
package main
import "fmt"
func main() {
//字符只能被單引號包裹,不能用雙引號,雙引號包裹的是字符串
var c1 byte = 'a'
var c2 byte = '0'
//當我們直接輸出type值時,就是輸出了對應字符的ASCII碼值
//'a' ==> 97
fmt.Println(c1, "--", c2)
//如果我們希望輸出對應字符,需要使用格式化輸出
fmt.Printf("c2 = %c c2 = %c", c1, c2)
}
但是如果我們保存的字符大於255,比如存儲漢字,這時byte類型就無法保存,此時可以使用uint或int類型保存
字符類型本質探討
-
字符型存儲到計算機中,需要將字符對應的碼值(整數)找出來
存儲:字符 --> 碼值 --> 二進制 --> 存儲
讀取: 二進制 -->碼值 --> 字符 --> 讀取
-
字符和碼值的對應關系是通過字符編碼表決定的(是規定好的)
-
Go語言的編碼都統一成了UTF-8。非常的方便,很統一,再也沒有編碼亂碼的困擾了
布爾型
布爾類型也叫做bool類型,bool類型數據只允許取值true或false
bool類型占1個字節
bool類型適用於邏輯運算,一般用於流程控制
字符串
字符串就是一串固定長度的字符連接起來的字符序列。Go的字符串是由單個字節連接起來的。Go語言的字符串的字節使用UTF-8編碼標識Unicode文本
-
字符串一旦賦值了,就不能修改了:在Go中字符串是不可變的。
-
字符串的兩種標識形式
-
雙引號,會識別轉義字符
var str = "abc\nabc" //輸出時會換行
-
反引號,以字符串的原生形式輸出,包括換行和特殊字符,可以實現防止攻擊、輸出源代碼等效果
var str string = `abc\nabc` //輸出時原樣輸出,不會轉義
-
-
字符串拼接方式"+"
var str string = "hello " + "world" str += "!"
-
當一行字符串太長時,需要使用到多行字符串,可以使用如下處理
//正確寫法 str := "hello" + " world!" fmt.Println(str) //錯誤寫法 str := "hello " + "world!" fmt.Println(str)
指針
- 基本數據類型,變量存的就是值,也叫值類型
- 獲取變量的地址,用&,比如var num int,獲取num的地址:&num
- 指針類型,指針變量存的是一個地址,這個地址指向的空間存的才是值,比如:var ptr *int = &num
- 獲取指針類型所指向的值,使用:*,比如,var ptr *int,使用*ptr獲取ptr指向的值
指針細節說明:
- 值類型,都有對應的指針類型,形式為*數據類型,比如int對應的指針就是*int,float64對應的指針類型就是*float64,依此類推。
- 值類型包括:基本數據類型、數組和結構體struct
值類型與引用類型
值類型和引用類型使用特點:
值類型:變量直接存儲值,內存通常在棧中分配
引用類型:變量存儲的是一個地址,這個地址對應的空間才真正存儲數據(值),內存通常在堆上分配,當沒有任何變量應用這個地址時,該地址對應的數據空間就成為一個垃圾,由GC來回收。
Golang中值類型和引用類型的區分
- 值類型:基本數據類型(int系列、float系列、bool、string)、數組和結構體
- 引用類型:指針、slice切片、map、管道chan、interface等都是引用類型
基本數據類型默認值
在Golang中,數據類型都有一個默認值,當程序員沒有賦值時,就會保留默認值,在Golang中,默認值也叫做零值。
基本數據類型默認值如下:
數據類型 | 默認值 |
---|---|
整型 | 0 |
浮點型 | 0 |
字符串 | "" |
布爾類型 | false |
package main
import "fmt"
func main() {
var a int
var b float32
var isTrue bool
var str string
//這里的%v,表示按照變量的值輸出
fmt.Printf("a = %v, b = %v, isTrue = %v, str = %v", a, b, isTrue, str)
fmt.Println("")
}
基本數據類型相互轉換
Golang和Java/C不同,Golang在不同類型的變量之間賦值時需要顯式轉換。也就是Golang中數據類型不能自動轉換。
基本語法:
表達式var_type(var_name) 將值v轉換為類型var_type
var_type:就是數據類型,比如int32, int64, float32等等
var_name:就是需要轉換的變量
var num int = 42
var float float64 = float64(num)
var ui uint8 = uint8(float)
fmt.Println(num, float, ui)
注意事項
-
Go中,數據類型的轉換可以是從表示范圍小-->表示范圍大,也可以 范圍大—>范圍小
-
被轉換的是變量存儲的數據(即值),變量本身的數據類型並沒有變化!
-
在轉換中,比如將int64轉成int8,編譯時不會報錯,只是轉換的結果是按溢出處理,和我們希望的結果不一樣。
-
數據的轉換必須顯式轉換,不能自動轉換
package main import "fmt" func main() { var n1 int32 = 12 var n2 int64 var n3 int8 n2 = n1 + 20 //int32 --> int64 錯誤 n3 = n1 + 20 //int32 --> int8 錯誤 n2 = int64(n1) + 20 //正確 n3 = int8(n1) + 20 //正確 }
-
定義一個int8類型的整數(var num int8 = 0),如果一直自加1,這個變量的值會是(0...127 -128 -127... 0 ...127)循環往復下去,而不會超過類型最大值的范圍
其他基本類型轉string類型
在程序開發中,我們經常需要將數值型轉成string類型,或者將string類型轉成數值型。
方式1:
func Sprintf(format string, a ...interface{}) string
Sprintf根據format參數生成格式化的字符串並返回該字符串。
package main
import "fmt"
func main() {
var num1 int = 99;
var num2 float64 = 23.456
var isTrue bool = true
var char byte = 'A'
var str string
str = fmt.Sprintf("%d", num1)
fmt.Printf("str類型為 %T str = %q\n",str, str)
str = fmt.Sprintf("%f", num2)
fmt.Printf("str類型為 %T str = %q\n",str, str)
str = fmt.Sprintf("%t", isTrue)
fmt.Printf("str類型為 %T str = %q\n",str, str)
str = fmt.Sprintf("%d", char)
fmt.Printf("str類型為 %T str = %q\n",str, str)
}
輸出結果為
str類型為 string str = "99"
str類型為 string str = "23.456000"
str類型為 string str = "true"
str類型為 string str = "65"
方式2:使用strconv包的函數
package main
import (
"fmt"
"strconv"
)
func main() {
var num1 int = 99;
var num2 float64 = 23.456
var isTrue bool = true
var str string
str = strconv.FormatInt(int64(num1), 10)
str = strconv.Itoa(num1)
fmt.Printf("str類型為 %T str = %q\n",str, str)
str = strconv.FormatFloat(num2, 'f', 10, 64)
fmt.Printf("str類型為 %T str = %q\n",str, str)
str = strconv.FormatBool(isTrue)
fmt.Printf("str類型為 %T str = %q\n",str, str)
}
輸出結果為
str類型為 string str = "99"
str類型為 string str = "23.4560000000"
str類型為 string str = "true"
string類型轉其他基本類型
方式1:使用strconv包的函數
package main
import (
"fmt"
"strconv"
)
func main() {
var str string = "true"
var str1 string = "123456"
var str2 string = "123.456"
var isTrue bool
var num int64
var num2 float64
isTrue, _ = strconv.ParseBool(str)
fmt.Printf("str類型為 %T str = %v\n",isTrue, isTrue)
num, _ = strconv.ParseInt(str1, 10, 64)
fmt.Printf("str類型為 %T str = %v\n",num, num)
num2, _ = strconv.ParseFloat(str2, 64)
fmt.Printf("str類型為 %T str = %v\n",num2, num2)
}
數據結果為:
str類型為 bool str = true
str類型為 int64 str = 123456
str類型為 float64 str = 123.456
注意:在將string類型轉成其它基本數據類型時,要確保string類型能夠轉成有效的數據。比如,我們可以把”123“轉成數字123,但是不能把”hello“轉成一個整數,如果這樣做,Golang直接將其轉成0,其它類型也是一樣的道理,float => 0, bool => false