Go語言系列-02-常用資料型別
Go語言常用資料型別
Go 語言中有豐富的資料型別,除了基本的整型、浮點型、布林型、字串、byte/rune 之外,
還有陣列、切片、函式、map、通道(channel)、結構體等。
Go語言的基本型別和其他語言大同小異。
整型
整型分為:有符號整型、無符號整型
其中比較特殊的整型資料型別有3個
-
unit 無符號整型,它在32位的作業系統上就是uint32,在64位的作業系統上就是uint64
-
int 有服號整型, 它在32位的作業系統上就是nit32,在64位的作業系統上就是int64
-
uintptr 無符號整型,用於存放一個指標
在使用 int 和 uint 型別時,不能假定他是32位或是64位的整型型別,而是要考慮程式可能執行在不同的平臺上,導致資料位數不一樣。所以,為了保持檔案的結構不會受到不同的平臺的影響,建議不要使用 int
有符號整形
- int、int8、int16、int32、int64 都屬於有符號整型的資料型別
無符號整型
- uint、uint8、uint16、uint32、uint64 都屬於無符號整型的資料型別
整型資料練習,資料型別轉換
package main import "fmt" func main() { // 十進位制 var i1 = 101 fmt.Println("--- 十進位制 ---") fmt.Printf("%d\n", i1) // 十進位制 fmt.Printf("%b\n", i1) // 十進位制 -> 二進位制 fmt.Printf("%o\n", i1) // 十進位制 -> 八進位制 fmt.Printf("%x\n", i1) // 十進位制 -> 十六進位制 // 八進位制 i2 := 077 fmt.Println("--- 八進位制 ---") fmt.Printf("%d\n", i2) // 八進位制 -> 十進位制 // 十六進位制 i3 := 0x123456f fmt.Println("--- 十六進位制 ---") fmt.Printf("%d\n", i3) // 十六進位制 -> 十進位制 fmt.Printf("%x\n", i3) // 十六進位制 // 檢視變數型別 fmt.Println("--- 檢視變數型別 ---") fmt.Printf("%T\n", i3) // 如果不指定資料型別,那麼預設則為int型別 // 宣告int8型別的變數 i4 := int8(9) // 明確指定int8型別,否則預設就是int型別 fmt.Printf("%T\n", i4) }
lichengguo@lichengguodeMacBook-Pro % go run main.go
--- 十進位制 ---
101
1100101
145
65
--- 八進位制 ---
63
--- 十六進位制 ---
19088751
123456f
--- 檢視變數型別 ---
int
int8
浮點型
浮點型分為 float32 和 float64 兩種型別
- float32
- float64
浮點型別比較簡單,不多說,直接看程式碼
package main import ( "fmt" "math" ) //浮點數 func main() { // math.MaxFloat32 float32最大值 // math.MaxFloat64 float64最大值 fmt.Println("--- 1. 浮點型最大值 ---") fmt.Println(math.MaxFloat32) fmt.Println(math.MaxFloat64) fmt.Println("---- 2. -------") f1 := 1.23456189 // float64 型別 fmt.Printf("%T\n", f1) // 預設Go語言中的小數都是 float64 型別 fmt.Printf("%f\n", f1) // 1.234562 預設只打印小數點後六位,會採取進一法保留六位小數 fmt.Printf("%.2f\n", f1) // 保留2位小數 1.23 會採用四捨五入保留2位小數 fmt.Println("---- 3. float32 ----") f2 := float32(1.23456) // float32 型別 fmt.Printf("%T\n", f2) // 顯示宣告 float32 型別 // float32 型別的值不能直接賦值給 float64 型別的變數 // f1 = f2 // 會報錯 fmt.Println("---- 4. ----") // 同類型的可以直接賦值 f3 := 1.2 // float64 型別 f1 = f3 fmt.Println(f1) fmt.Printf("%T\n", f1) fmt.Printf("%T\n", f3) }
執行結果
lichengguo@lichengguodeMacBook-Pro % go run main.go
--- 1. 浮點型最大值 ---
3.4028234663852886e+38
1.7976931348623157e+308
---- 2. -------
float64
1.234562
1.23
---- 3. float32 ----
float32
---- 4. ----
1.2
float64
float64
布林型
Go語言中以 bool 型別進行宣告布林型資料,布林型資料只有 true 和 false 兩個值
- 布林型別變數的預設值是 false
- Go語言不允許將 整型 強制轉換為 布林型
- 布林型無法參與數值運算,也無法與其他型別進行轉化
package main
import (
"fmt"
)
func main() {
b1 := true
var b2 bool // 預設是false
fmt.Printf("%T\n", b1)
fmt.Printf("%T value:%v\n", b2, b2)
}
執行結果
lichengguo@lichengguodeMacBook-Pro day01 % go run main.go
bool
bool value:false
字串
Go語言中 字串 是用 雙引號" " 包裹的,用 單引號' ' 包裹的是 字元,Go語言裡的字串內部實現使用的是**UTF8 **編碼
-
ASCII編碼中: 一個字元 'A' 佔用1個位元組(Byte)
-
UTF8編碼中: 一個字元 'A' 佔用1個位元組(Byte),一個漢字 '中' 一般佔用3個位元組(Byte)
-
小知識:
1位元組(Byte) = 8bit (8個二進位制位)
1024位元組(Byte) = 1KB
字串和字元這兩者之間的區別
字串
- 雙引號
- 字串有一個或者多個 字元 組成
- 字串都是隱藏了一個結束符:
\0
字元
- 單引號
- 往往只包含一個字元,轉義字元除外,如
\n
下面通過程式碼具體來看一下
package main
import (
"fmt"
)
func main() {
// 字元
fmt.Println("---- 1. 字元 ----")
ch := 'a' // 簡短宣告變數並且賦值
fmt.Println("ch =", ch)
fmt.Printf("%T\n", ch)
// 字串
fmt.Println("---- 2. 字串 ----")
s1 := "a"
fmt.Println("s1 =", s1)
fmt.Printf("%T\n", s1)
}
執行結果
從結果可以看出,字元型別本質上是一個int32 型別
lichengguo@lichengguodeMacBook-Pro day01 % go run main.go
---- 1. 字元 ----
ch = 97 // ASCII編碼97對應的是小寫字母a
int32
---- 2. 字串 ----
s1 = a
string
轉義符 \
package main
import (
"fmt"
)
func main() {
// \ 反斜槓是具有特殊含義的,應該告訴程式寫的 \ 就是一個單純的 \
// path := "D:\\Go\\src\\studygo\\day01"
// path := "'D:\\Go\\src\\studygo\\day01'"
path := "\"D:\\Go\\src\\studygo\\day01\""
fmt.Println(path)
}
多行字串
package main
import (
"fmt"
)
func main() {
// 多行字串
s2 := `
aaa
bbb
ccc
`
fmt.Println(s2)
s3 := `D:\Go\src\code.oldboyedu.com\studygo\day01`
fmt.Println(s3)
}
字串的一些常用操作
package main
import (
"fmt"
"strings"
)
func main() {
// 字串相關操作
// 1. 統計位元組數
fmt.Println("---- 1. 統計位元組數 ----")
s1 := "hello中國"
// 注意 len函式 統計字串的時候,是統計【位元組數長度】,而不是字元的個數
// 在utf8編碼中,一個英文字元佔用1個位元組,一箇中文字元一般佔用3個位元組
fmt.Println(len(s1)) // 此處的11是位元組數長度,而不是字元的個數
// 2. 字串拼接
fmt.Println("---- 2. 字串拼接 ----")
name := "tom"
world := "dsb"
ss := name + world // 拼接方式1
fmt.Println(ss) // tomdsb
ss1 := fmt.Sprintf("%s - %s", name, world) // 拼接方式2
fmt.Println(ss1) // tom - dsb
// 3. strings包相關操作
fmt.Println("---- 3. strings包相關操作 ----")
// 3.1 分割
fmt.Println("---- 3.1 分割 ----")
s3 := `D:\Go\src\studygo\day01`
ret := strings.Split(s3, "\\") // 注意這裡的 \\ 前面的反斜槓是為了不讓後面的反斜槓具有特殊意義
fmt.Println(ret) // [D: Go src studygo day01]
// 3.2 包含
fmt.Println("---- 3.2 包含 ----")
fmt.Println(strings.Contains(ss, "dsb")) // true
// 3.3 字首
fmt.Println("---- 3.3 字首 ----")
fmt.Println(strings.HasPrefix(ss, "tom")) // true
// 3.4 字尾
fmt.Println("---- 3.4 字尾 ----")
fmt.Println(strings.HasSuffix(ss, "dsb")) // true
// 3.5 查詢字串出現的索引
fmt.Println("---- 3.5 查詢字串出現的索引 ----")
s5 := "abcdeb"
fmt.Println(strings.Index(s5, "c")) // 2 從0開始計數
fmt.Println(strings.LastIndex(s5, "eb")) // 4
// 單獨的字母、漢字、符號並且用單引號括起來的表示一個字元
// 雙引號的是字串了
fmt.Println("-----------------------------")
s6 := 'c'
fmt.Printf("s6: %T\n", s6) // int32
s7 := '中'
fmt.Printf("s7: %T\n", s7) // int32
s8 := "c"
fmt.Printf("s8: %T\n", s8) // string
// 3.6 切片拼接
fmt.Println("---- 3.6 切片拼接 ----")
fmt.Println(strings.Join(ret, "+")) // D:+Go+src+studygo+day01
}
lichengguo@lichengguodeMacBook-Pro day01 % go run main.go
---- 1. 統計位元組數 ----
11
---- 2. 字串拼接 ----
tomdsb
tom - dsb
---- 3. strings包相關操作 ----
---- 3.1 分割 ----
[D: Go src studygo day01]
---- 3.2 包含 ----
true
---- 3.3 字首 ----
true
---- 3.4 字尾 ----
true
---- 3.5 查詢字串出現的索引 ----
2
4
-----------------------------
s6: int32
s7: int32
s8: string
---- 3.6 切片拼接 ----
D:+Go+src+studygo+day01
byte和rune
Go語言中的 字元 有兩種資料型別
- uint8型別,或者叫做 byte 型別,代表了ASCII編碼的一個字元
- rune型別,代表了UTF-8編碼的一個字元
當需要處理中文、日文等其他複合字符時,則需要用到rune
型別。rune
型別實際上就是一個int32
型別
遍歷字串
package main
import (
"fmt"
)
// Go語言裡的字串內部實現使用的是UTF8編碼
func main() {
s := "Hello中國"
n := len(s) // len 的結果是位元組的長度,而不是字元的數量
fmt.Println(n) // 11
// 遍歷字串
// Go語言裡的字串內部實現使用的是UTF8編碼,而rune型別,代表了UTF8編碼的一個[字元]
s1 := []rune(s) // 轉換成rune型別的切片
fmt.Println("s1:", s1, len(s1)) // s1: [72 101 108 108 111 228 184 173 229 155 189] 7
for i := 0; i < len(s1); i++ {
fmt.Printf("%c", s1[i]) // %c 字元
}
fmt.Println()
// 下面這種方法會亂碼
for i := 0; i < len(s); i++ {
fmt.Printf("%c", s[i])
}
fmt.Println()
// 使用range這種方式去遍歷字串,得到每個字元。
// 不管有沒有中文都能正常顯示
for index, c := range s {
// 注意這裡的index並不是按照1 2 3 4 這樣+1上去的,是按照字元所在的位元組位置,1箇中文一般等於3個位元組
fmt.Printf("資料型別:%T - index:%d -- 字元:%c\n", c, index, c)
}
}
輸出
lichengguo@lichengguodeMacBook-Pro day01 % go run test.go
11
s1: [72 101 108 108 111 20013 22269] 7
Hello中國
Helloä¸å½
資料型別:int32 - index:0 -- 字元:H
資料型別:int32 - index:1 -- 字元:e
資料型別:int32 - index:2 -- 字元:l
資料型別:int32 - index:3 -- 字元:l
資料型別:int32 - index:4 -- 字元:o
資料型別:int32 - index:5 -- 字元:中
資料型別:int32 - index:8 -- 字元:國
型別轉換
package main
import (
"fmt"
)
func main() {
// 型別轉換
// int --> float
fmt.Println("---- int --> float ----")
n1 := 10
f := float64(n1)
fmt.Println(f) // 10
fmt.Printf("%T\n", f) // f:float64
// float --> int 會把小數部分去掉
fmt.Println("---- float --> int ----")
f1 := float64(10.1)
n2 := int(f1)
fmt.Println(n2) // 10
// string <--> rune
fmt.Println("---- string <--> []rune ----")
s1 := "tom"
s2 := []rune(s1)
fmt.Println(s2) // [116 111 109] ASCII編碼對照表
s3 := "中國good"
s4 := []rune(s3) // string --> []rune
fmt.Println(s4) // [20013 22269 103 111 111 100]
fmt.Printf("%T\n", s4) // 資料型別 []int32
s5 := string(s4) // []rune --> string
fmt.Println(s5) // 中國
// string <--> byte
fmt.Println("---- string <--> []byte ----")
s6 := "你好hello"
s7 := []byte(s6)
fmt.Println(s7) // [228 189 160 229 165 189 104 101 108 108 111] 一箇中文字元佔3個位元組
fmt.Printf("%T\n", s7) // []uint8
// 其他
//s8 := []byte{'A', 1, 3, 'B', '漢'} byte裡面不能存中文,會報錯 constant 27721 overflows byte
fmt.Println("---- other ----")
s8 := []byte{'A', 1, 3, 'B'}
fmt.Println(s8) // [65 1 3 66]
fmt.Printf("%T\n", s8) // []uint8
s9 := []rune{'中', 'A', 1, 3}
fmt.Println(s9) // [20013 65 1 3]
fmt.Printf("%T\n", s9) // []int32
}
輸出
lichengguo@lichengguodeMacBook-Pro day01 % go run main.go
---- int --> float ----
10
float64
---- float --> int ----
10
---- string <--> []rune ----
[116 111 109]
[20013 22269 103 111 111 100]
[]int32
中國good
---- string <--> []byte ----
[228 189 160 229 165 189 104 101 108 108 111]
[]uint8
---- other ----
[65 1 3 66]
[]uint8
[20013 65 1 3]
[]int32