文章目錄
1. Go語言數據類型
1.1 數據類型分類
Go語言數據類型大致可以分爲兩類
基礎類型,其中就包括了我們最常見的一些類型
類型 名稱 長度 零值 說明 bool 布爾類型 1 false 其值不爲真即爲家,不可以用數字代表true或false byte 字節型 1 0 uint8別名 rune 字符類型 4 0 專用於存儲unicode編碼,等價於uint32 int, uint 整型 4或8 0 32位或64位 int8, uint8 整型 1 0 -128 ~ 127, 0 ~ 255 int16, uint16 整型 2 0 -32768 ~ 32767, 0 ~ 65535 int32, uint32 整型 4 0 -21億 ~ 21 億, 0 ~ 42 億 int64, uint64 整型 8 0 float32 浮點型 4 0.0 小數位精確到7位 float64 浮點型 8 0.0 小數位精確到15位 complex64 複數類型 8 complex128 複數類型 16 uintptr 整型 4或8 ⾜以存儲指針的uint32或uint64整數 string 字符串 “” utf-8字符串 複合類型, 這些類型構成了Go語言的特點
- 指針 (pointer)
- 數字 (array)
- 切片 (slice)
- 字典(map)
- 通道 (chan)
- 結構體 (struct)
- 接口 (interface)
2. 布爾類型
- 也叫做bool類型
- bool 類型數據的值只能是true 或者 false
- bool 類型默認值是false
- bool 類型 佔1個字節
- bool類型一般用於流程控制
- bool類型不能接受其他類型賦值
- bool類型不支持自動或者強制類型裝換
package main
import "fmt"
var a bool
func main() {
//a = 1 // 錯誤 cannot use 1 (type int) as type bool in assignment
fmt.Printf("type = %T\n", a)
fmt.Printf("value = %v\n", a)
if a {
fmt.Println("this is true")
} else {
fmt.Println("this is false")
}
}
type = bool
value = false
this is false
3. 整數類型
整數類型就是存放整數值得
int類型和uint類型自動匹配平臺長度
類型 有無符號 佔用空間 範圍 備註 int 有 32位系統4個字節
64位系統8個字節uint 無 32位系統4個字節
64位系統8個字節rune 有 與int32一樣 等價int32,表示一個Unicode碼 byte 無 與uint8等價 0~255 存儲字符使用 Go語言的整型默認聲明是int型
通常int和int32被認爲是兩種不同的類型,編譯器不會做自動裝換
整數類型可以進行數值運算 (加減乘除和求餘)
整數類型可以進行比較運算(> , < ,==, >= , <= ,!=)
兩個不同類型的整數不能比較,即使他們的值看着相同也不行
3.1 查詢某個變量的字節大小和數據類型
package main
import (
"fmt"
"unsafe"
)
var v1 int8
var v2 int16 = 88
var v3 int32 = 8978923
var v4 = 8978989
var v5 int64
var v6 rune
func main(){
fmt.Printf("v1 類型是%T, v1 佔的字節數是%d\n",v1,unsafe.Sizeof(v1))
fmt.Printf("v2 類型是%T, v2 佔的字節數是%d\n",v2,unsafe.Sizeof(v2))
fmt.Printf("v3 類型是%T, v3 佔的字節數是%d\n",v3,unsafe.Sizeof(v3))
fmt.Printf("v4 類型是%T, v4 佔的字節數是%d\n",v4,unsafe.Sizeof(v4))
fmt.Printf("v5 類型是%T, v5 佔的字節數是%d\n",v5,unsafe.Sizeof(v5))
fmt.Printf("v6 類型是%T, v6 佔的字節數是%d\n",v6,unsafe.Sizeof(v6))
}
v1 類型是int8, v1 佔的字節數是1
v2 類型是int16, v2 佔的字節數是2
v3 類型是int32, v3 佔的字節數是4
v4 類型是int, v4 佔的字節數是8
v5 類型是int64, v5 佔的字節數是8
v6 類型是int32, v6 佔的字節數是4
3.2 如何證明int和int64不是同一種類型
package main
import (
"fmt"
"unsafe"
)
var v1 = 99
var v2 int64
func main(){
fmt.Printf("v1的類型是%T,v1佔的字節長度是%d\n",v1,unsafe.Sizeof(v1))
fmt.Printf("v2的類型是%T,v2佔的字節長度是%d\n",v2,unsafe.Sizeof(v2))
// 將v1的值賦給v2
//v2 = v1 // 錯誤 cannot use v1 (type int) as type int64 in assignment
v2 = int64(v1) // 通過
fmt.Printf("v2的值是%v,v2的類型是%T",v2,v2)
}
v1的類型是int,v1佔的字節長度是8
v2的類型是int64,v2佔的字節長度是8
v2的值是99,v2的類型是int64
3.3 不同的整數類型不能比較
package main
import "fmt"
var a int32
var b int64
func main(){
a,b=8,8
if a == b{ //invalid operation: a == b (mismatched types int32 and int64)
fmt.Println("===")
}
}
4. 浮點型
浮點型用於表示包含小數點的數據,例如 1.234 , 0.99 , -9.9等就是一個浮點型數據,Go語言中的浮點型採用 IEEE-754 標準的表達方式
Go語言定義兩個浮點類型float32和float64,其中float32相當於C語言中的float類型, float64等價於C語言中的double類型
類型 佔用存儲空間 範圍 單精度float32 4字節 -3.4028234663852886e+38~3.4028234663852886e+38 雙精度float64 8字節 -1.7976931348623157e+308~1.7976931348623157e+308
4.1 浮點數 = 符號位+指數位+尾數位
4.2 浮點數都是有符號的
package main
import "fmt"
func main(){
var p float32 = 99.99
fmt.Println(p)
var p1 float32 = -0.33
fmt.Println(p1)
var p2 float64 = -79787878.9
fmt.Println(p2)
}
99.99
-0.33
-7.97878789e+07
4.3 float64 比float32準確
小數部分可能丟失,造成精度損失,要保存高精度的數應該選擇float64
Go語言的浮點型默認是float64類型
package main
import "fmt"
func main(){
var p1 float32 = 897.0000023
var p2 float64 = 897.0000023
fmt.Println("p1 = ",p1)
fmt.Println("p2 = ",p2)
p3 := -12.90
// GO語言默認是使用float64類型
fmt.Printf("p3 type = %T",p3)
}
p1 = 897
p2 = 897.0000023
p3 type = float64
4.4 浮點是強制轉換
需要說明float32 和 float64 是兩種類型,不能直接相互賦值
package main
import "fmt"
var f1 float32
var f2 float64
func main() {
f2 = 1212.09
fmt.Printf("f2 type is %T, value is %v\n",f2,f2)
// 運行報錯
//cannot use f2 (type float64) as type float32 in assignment
f1 = f2
fmt.Printf("f1 type is %T, value is %v\n",f1,f1)
}
我們看看浮點數float32 和 float64類型怎麼轉換
package main
import "fmt"
var f1 float32
var f2 float64
func main() {
f2 = 1212.09
fmt.Printf("f2 type is %T, value is %v\n",f2,f2)
// 強制轉換成float32類型
f1 = float32(f2)
fmt.Printf("f1 type is %T, value is %v\n",f1,f1)
}
f2 type is float64, value is 1212.09
f1 type is float32, value is 1212.09
5. 字符類型
Go語言中支持兩種字符類型 分別是byte 和 rune
byte型 ,實際上是uint8類型的別稱,代表了ASCII碼的一個字符
rune 類型,代表一個unicode 字符 ,實際是一個int32類型,在處理中文,日文或者其他符合類型時需要用到,Go語言中使用特殊的rune類型來處理Unicode,讓基於Unicode的文本處理更爲方便
package main import "fmt" func main() { var a byte = 'a' var b rune = '中' // a的值`a`對應的ASCII編碼是97 實際類型是uint8 fmt.Printf("a value = %d type = %T\n", a, a) // b的值`中`對應的Unicode碼是20013 實際類型是int32 fmt.Printf("b value = %d type = %T\n", b, b) // 輸出對應的字符 fmt.Printf("a = %c b = %c",a,b) }
a value = 97 type = uint8 b value = 20013 type = int32 a = a b = 中
Unicode 是字符集,ASCII 也是一種字符集,UTF-8是一種編碼規則
字符集爲每一個字符分配一個唯一的ID,我們使用的所有字符在unicode字符集中都有唯一的ID對應.
utf-8 是編碼規則,將unicode字符集中的ID以某種形式進行編碼
在Go語言中,字符的本質是一個數字,格式化輸出時%c,會輸出該數字對應的unicode字符
package main import "fmt" func main(){ var v1 int8 = 102 fmt.Printf("v1 = %c\n",v1) var v2 int = 22381 fmt.Printf("v2 = %c\n",v2) }
v1 = f v2 = 坭
字符串是可以進行運算的
package main import "fmt" func main() { var v1 int = 10 v1 += 97 fmt.Printf("v1 = %d,unicode = %c",v1,v1) }
v1 = 107,unicode = k
6. string類型
Go語言字符串數據對應的字節數組,字符串的只讀屬性禁止了在程序中對底層字節數組的元素修改,字符串賦值只是賦值了數據地址和對應長度,而不會底層數據的賦值
字符串是一串固定長度的字符連接起來的字符序列,Go語言的字符串的字節使用utf-8編碼標識的unicode文本
字符串類型也就是string類型定義很簡單
package main
import "fmt"
var s1 string
func main() {
s1 = "Celtic 凱爾特人"
s2 := "Lakers 湖人"
var s3 string = "Rocket 火箭"
fmt.Printf("s1 = %s type = %T\n",s1,s1)
fmt.Printf("s2 = %s type = %T\n",s2,s2)
fmt.Printf("s3 = %s type = %T\n",s3,s3)
}
s1 = Celtic 凱爾特人 type = string
s2 = Lakers 湖人 type = string
s3 = Rocket 火箭 type = string
字符串的內容可以用類似數組下標的方式獲取,但是與數組不同的是,字符串的內容不能在初始化之後修改
package main
import "fmt"
func main() {
var s1 string = "hello world ~~"
// 使用內置函數len()獲取字符串長度
l := len(s1)
fmt.Printf("s1 的長度是 : %d\n",l)
// 獲取第一個字符
ch1 := s1[8]
fmt.Printf("%c ch1 = %v,type = %T\n",ch1,ch1,ch1)
}
s1 的長度是 : 14
r ch1 = 114,type = uint8
看一個錯誤的例子
package main
import "fmt"
func main() {
var s1 string = "hello world ~~"
//會報編譯錯誤
s1[0] = "H"
fmt.Println(s1[0])
}
cannot assign to s1[0]
字符串的兩種表示形式
- 雙引號 ,字符串的值在書寫在雙引號中是最常見的表達方式,也稱爲字符串字面量,這種形式不能跨行,如果字符串太長,可以使用 + 拼接
- 反引號, 以字符串原生樣式輸出,包括換行和特殊字符
package main
import "fmt"
func main() {
s0 := "hello" +
"world"
s0 += "\n 中國"
fmt.Println(s0)
}
helloworld
中國
package main
import "fmt"
func main() {
// 定義多行字符串
var s1 string = `怒髮衝冠
憑欄處瀟瀟雨歇
擡望眼
仰天長嘯`
fmt.Println(s1)
}
怒髮衝冠
憑欄處瀟瀟雨歇
擡望眼
仰天長嘯
以字節數組方式遍歷數組
package main
import "fmt"
func main(){
var s1 string = "golang 中國"
// 因爲字符佔1個字節,漢字佔3個字節 所以參數s1的長度是13
l := len(s1)
for i:= 0 ;i<l;i++{
ch := s1[i] // 依據下標取字符串中的字符,類型爲byte
fmt.Printf("%T,%d,%d\n",ch,i,ch)
}
}
uint8,0,103
uint8,1,111
uint8,2,108
uint8,3,97
uint8,4,110
uint8,5,103
uint8,6,32
uint8,7,228
uint8,8,184
uint8,9,173
uint8,10,229
uint8,11,155
uint8,12,189
以unicode字符遍歷數組
package main
import "fmt"
func main(){
var s1 string = "golang 中國"
for i,v := range s1{
// v是rune類型
fmt.Printf("%d,%T,%d,%c\n",i,v,v,v)
}
}
0,int32,103,g
1,int32,111,o
2,int32,108,l
3,int32,97,a
4,int32,110,n
5,int32,103,g
6,int32,32,
7,int32,20013,中
10,int32,22269,國
6.1 補充1:基本數據類型轉換
Go語言中不同類型變量之間相互賦值時需要顯式轉換(不能自動轉換)
轉換的表達式 T(v) , 意思是將v轉換成T類型
多見於整數的不同類型之間的轉換,或者不同浮點數類型之間的轉換,或是整數與浮點數之間的相互轉
package main
import "fmt"
func main() {
var v1 int8 = 99
var v2 int
fmt.Printf("v1 type is %T,value is %d\n",v1,v1)
fmt.Printf("v2 type is %T,value is %d\n",v2,v2)
v2 = int(v1)
fmt.Printf("v2 type is %T,value is %d\n",v2,v2)
}
v1 type is int8,value is 99
v2 type is int,value is 0
v2 type is int,value is 99
GO語言中數據類型的值範圍可以從大向小轉換,也可以從小向大轉換
package main
import "fmt"
func main() {
// int8 的範圍是 -128 ~ 127
var v1 int8
var v2 int64 = 9999999
var v3 float64
// 不會報錯, 結果是按溢出處理
v1 = int8(v2)
v3 = float64(v2)
fmt.Printf("%T, %d\n",v1,v1)
fmt.Printf("%T, %f\n",v3,v3)
}
int8, 127
float64, 9999999.000000
6.2 補充2 基本數據類型和string 類型的轉換
在實際應用中,string 類型和基礎類型的相互轉換非常常見
例如,整數類和浮點數類型,bool型等與string類型之間的轉換
基礎類型轉成string類型
方法1: 通過包 fmt 包的Sprintf()函數去實現
package main
import "fmt"
func main(){
var v1 int64 = 99998767
var f float64 = 90.7978
var b bool = true
var ch byte = 'w'
var s string
s = fmt.Sprintf("%d",v1)
fmt.Printf("v2 = %s, %T\n",s,s)
s = fmt.Sprintf("%f",f)
fmt.Printf("v2 = %s, %T\n",s,s)
s = fmt.Sprintf("%t",b)
fmt.Printf("v2 = %s, %T\n",s,s)
s = fmt.Sprintf("%c",ch)
fmt.Printf("v2 = %s, %T\n",s,s)
}
v2 = 99998767, string
v2 = 90.797800, string
v2 = true, string
v2 = w, string
基礎數據類型轉換成string類型
方法2 : 使用 strconv 包中的函數實現
package main
import (
"fmt"
"strconv"
)
func main() {
var n int8 = 12
var f float64 = 23.001
var b bool = false
// FormatInt函數中傳入的第一個參數應該是int64類型
s := strconv.FormatInt(int64(n),10)
fmt.Printf("s = %s and type = %T\n",s,s)
// 其中的參數說明參考文檔
s = strconv.FormatFloat(f,'f',10,64)
fmt.Printf("s = %s and type = %T\n",s,s)
s = strconv.FormatBool(b)
fmt.Printf("s = %s and type = %T\n",s,s)
}
s = 12 and type = string
s = 23.0010000000 and type = string
s = false and type = string
strconv 包中有其他的方法可以將string類型轉換成整數類型,浮點數類型,bool類型,函數名爲 ParseInt() ParseBool() ParseFloat() **ParseUint()
package main
import (
"fmt"
"strconv"
)
func main() {
var s1 string = "99090"
var s2 string = "12.090"
var s3 string = "true"
var s4 string = "97"
var s5 string = "helloworld"
n, _ := strconv.ParseInt(s1, 10, 64)
fmt.Printf("n = %d,type = %T\n", n, n)
f, _ := strconv.ParseFloat(s2, 64)
fmt.Printf("f = %f,type = %T\n", f, f)
b, _ := strconv.ParseBool(s3)
fmt.Printf("b = %t,type = %T\n", b, b)
n2, _ := strconv.ParseUint(s4, 10, 64)
fmt.Printf("n2 = %d,type = %T\n", n2, n2)
// 錯誤原因是s5的有效數據不能轉換成指定的類型
n3, err := strconv.ParseInt(s5, 10, 64)
if err !=nil{
fmt.Println("error = ",err)
}else{
fmt.Printf("n = %d,type = %T\n", n3, n3)
}
}
n = 99090,type = int64
f = 12.090000,type = float64
b = true,type = bool
n2 = 97,type = uint64
error = strconv.ParseInt: parsing "helloworld": invalid syntax
7. 補充3 Go語言中常見轉義符
轉義符 | 含義 |
---|---|
\r | 回車符(返回行首) |
\n | 換行符 |
\t | 製表符 |
\’ | 單引號 |
\" | 雙引號 |
\\ | 反斜槓 |
package main
import "fmt"
func main() {
var s1 string = "\"D:\\Go\\bin\\go.exe\""
fmt.Println(s1)
}
"D:\Go\bin\go.exe"