一、整型
1.整型
在Golang中包含有符號和無符號兩種整形,按可保存值的範圍大小可分爲以下:
有符號整型: int8 (-128~127) int16 (-32768~32767) int32 (-2147483648~2147483647) int64 (-9223372036854775808~9223372036854775807) int 在32位操作系統上使用默認爲int32 在64位操作系統上使用默認爲int64 無符號整型: uint8 (0~255) uint16 (0~65535) uint32 (0~4294967295) uint64 (0~18446744073709551615) int 在32位操作系統上使用默認爲uint32 在64位操作系統上使用默認爲uint64
如果要使用比int64範圍還大的整數類型,則需要使用Golang提供的big.Int包提供的類型。
2.整型之間的轉換
var num1 int8 = 18 var num2 int16 = 20 num3 := int16(num1) + num2 // 不能將int8和int16類型相加,需要轉換爲相同類型 fmt.Println(num3)
基本和C/C++的類型強制轉換一樣。
3.整型和字符串之間的轉換
整型轉換爲字符串:
v1 := 19 result := strconv.Itoa(v1) // v1爲int類型,可以直接轉換爲string fmt.Println(result, reflect.TypeOf(result)) // 打印result類型,輸出string var v2 int8 = 19 data := strconv.Itoa(int(v2)) // 這裏需要將int8轉換爲int,因爲Itoa只接受int類型參數 fmt.Println(data)
字符串轉換爲整型:
str1 := "666" res, err := strconv.Atoi(str1) if err == nil { // "666"可以被轉換爲整型,所以err爲空 fmt.Println(res) // 輸出666 } str2 := "SB" res, err = strconv.Atoi(str2) fmt.Println(res, err) // "SB"不能轉換爲整型,所以res輸出0,err輸出:strconv.Atoi: parsing "SB": invalid syntax,
4.進制轉換
十進制轉二進制、八進制、十六進制:
vv := 99 // 將十進制轉換爲二進制 rr1 := strconv.FormatInt(int64(vv), 2) // 第一個參數必須爲int64類型,第二個參數代表要轉換爲的進制 fmt.Println(rr1, reflect.TypeOf(rr1)) // 輸出1100011 string
vv := 99 // 將十進制轉換爲八進制 rr1 := strconv.FormatInt(int64(vv), 8) fmt.Println(rr1, reflect.TypeOf(rr1)) // 輸出143 string
vv := 99 // 將十進制轉換爲十六進制 rr1 := strconv.FormatInt(int64(vv), 16) fmt.Println(rr1, reflect.TypeOf(rr1)) // 輸出63 string
二進制、八進制、十六進制轉十進制整型:
data := "1001000110" // result爲轉換後的十進制(永遠是int64類型),err爲錯誤信息 // 第一個參數爲需要轉換的二進制字符串,第二個參數指定轉換前的進制, // 第三個參數用於約束轉換的範圍,例如16代表int16,如果待轉換的二進制值大於int16的範圍,則err會報錯。0代表int result, err := strconv.ParseInt(data, 2, 16) if err == nil { fmt.Println(result,reflect.TypeOf(result)) // 打印 582 int64 }
特別注意第三個參數,只用作約束範圍,不代表返回值result的類型。
進制間轉換關係圖:
二、常見數學運算
package main import ( "fmt" "math" ) func main() { fmt.Println(math.Abs(-19)) // 取絕對值 fmt.Println(math.Floor(3.14)) // 向下取整 fmt.Println(math.Ceil(3.14)) // 向上取整 fmt.Println(math.Round(3.3478)) // 四捨五入 fmt.Println(math.Round(3.3478*100) / 100) // 保留兩位小數 fmt.Println(math.Mod(11, 3)) // 同11%3,取餘 fmt.Println(math.Pow(2, 5)) // 計算次方,2的5次方 fmt.Println(math.Pow10(2)) // 計算10次方,2的10次方 fmt.Println(math.Max(1,2)) // 取較大值(只能輸入兩個值) fmt.Println(math.Min(1,2)) // 取較小值(只能輸入兩個值) }
三、指針、聲明變量、new
1.聲明變量
var v1 int // 在內存中開闢一塊內存用於存放int類型的值,默認爲0 v2 := 999 // 在內存中開闢一塊內存用於存放int類型的值,賦值爲999
2.指針
與C語言幾樣,只是聲明和定義形式不同:
var ptr1 *int // 聲明一個int類型的指針變量,該指針指向的是nil,也就是空指針
3.new關鍵字
ptr2 := new(int) // 開闢一個用於存放int的內存塊A,存放的默認值爲0,另外再創建一個用於存放int指針的內存塊,存放A的地址。 *ptr2 = 999 // 給ptr2指向的內存塊賦值爲999
new關鍵字,用於創建一塊內存塊,並幫我們初始化,並返回一個指向其空間的指針。
四、超大整型
超出int64的時候,就需要使用超大整型,big.Int類型。
1.定義超大整型
var v1 big.Int var v2 *big.Int v3 := new(big.Int)
2.寫入數據
package main import ( "fmt" "math/big" ) func main() { var v1 big.Int v1.SetInt64(10) // 將1990寫入v1 fmt.Println(v1) // 輸出{false [9182637123817232]} v2:=new(big.Int) v2.SetString("9182637123817232",10) // 將其以10進制寫進v1,2進制8進制一樣 fmt.Println(*v2) // 做加法 res := new(big.Int) res.Add(&v1,v2) // Add方法要穿指針 fmt.Println(res) }
五、浮點型
1.浮點型變量
float32和float64,分別用32bit和64bit來存儲浮點數。
var f1 float32 // 聲明f1爲float32類型 f1 = 3.14 f2 := 9.99 // 默認爲float64 f3 := float64(f1)+f2 // f1和f2不能直接相加 fmt.Println(f3)
注意,不指定類型的情況下,默認使用float64類型,在做運算時要注意類型一致。
2.使用decimal精準浮點
1)在goland IDE中使用命令行安裝第三方包decimal
先在項目的Setting頁面設置GOPATH:
在goland的terminal中使用命令:
D:\golang_workspace\src\day1>go env -w GOPROXY=https://goproxy.cn D:\golang_workspace\src\day1>go get github.com/shopspring/decimal
在執行go get後,可以在%GOPATH%/src目錄下看到decimal源碼:
在%GOPATH%/pkg目錄下可以看到編譯好的靜態庫:
2)使用decimal
package main import ( "fmt" "github.com/shopspring/decimal" ) func main() { var v1 = decimal.NewFromFloat(0.0000000000019) var v2 = decimal.NewFromFloat(0.29) var v3 = v1.Add(v2) // 加法 var v4 = v1.Sub(v2) // 減法 var v5 = v1.Mul(v2) // 乘法 var v6 = v1.Div(v2) // 除法 fmt.Println(v3, v4, v5, v6) // 0.2900000000019 -0.2899999999981 0.000000000000551 0.0000000000065517 var price = decimal.NewFromFloat(3.4675) var d1 = price.Round(2) // 四捨五入保留兩位小數 var d2 = price.Truncate(2) // 截取保留兩位小數 fmt.Println(d1, d2) // 打印3.47和3.46 }
六、字符串
1.golang中字符串的本質
golang中字符串的本質是UTF-8編碼的序列
var name string = "中國" fmt.Println(name[0],strconv.FormatInt(int64(name[0]),2)) // 打印"中國"字符串的第一個字節 打印228 11100100 fmt.Println(name[1],strconv.FormatInt(int64(name[1]),2)) // 打印"中國"字符串的第二個字節 打印184 10111000 fmt.Println(name[2],strconv.FormatInt(int64(name[2]),2)) // 打印"中國"字符串的第三個字節 打印173 10101101 fmt.Println(name[3],strconv.FormatInt(int64(name[3]),2)) // 打印"中國"字符串的第四個字節 打印229 11100101 fmt.Println(name[4],strconv.FormatInt(int64(name[4]),2)) // 打印"中國"字符串的第五個字節 打印155 10011011 fmt.Println(name[5],strconv.FormatInt(int64(name[5]),2)) // 打印"中國"字符串的第六個字節 打印189 10111101 fmt.Println(len(name)) // 獲取name中字符串的字節長度 打印6
2.字節集合與字符串
將字符串轉換爲一個字節的"集合":
// 將字符串轉換爲字節"集合" byteSet := []byte(name) fmt.Println(byteSet) // 打印[228 184 173 229 155 189],其中包含6個字節的十進制表示
將字節"集合"轉換爲字符串:
// 將字節集合轉換爲string byteList := []byte{228,184,173,229,155,189} fmt.Println(string(byteList)) // 打印"中國"
3.rune類型
rune類型一般用於代表一個unicode碼點,例如一個漢字:
runeSet:= []rune(name) // 將"中國"轉換爲rune"集合" fmt.Println(runeSet) // 打印 [20013 22269] fmt.Println(runeSet[0]) // 拿到第一個rune,打印 20013。這個rune代表的就是"中"字,三個字節的十進制表示 fmt.Println(strconv.FormatInt(int64(runeSet[0]),16)) // 轉換爲16進製爲4e2d
在Unicode碼錶中,4e2d的16進制數就表示"中"字。
獲取字符串中中文的長度:
runeLength := utf8.RuneCountInString(name) fmt.Println(runeLength) // 打印2,表示有2個漢字
4.字符串常見操作
1)字符串長度
len(name) // 獲取字符串的字節長度 utf8.RuneCountInString(name) // 獲取字符長度(字符個數)
2)是否以XX開頭或結尾
strings.HasPrefix(name,"中") // 是否以"中"字開頭 strings.HasSuffix(name,"國") // 是否以"國"字結尾
3)大小寫轉換
strings.ToUpper(name) // 轉換爲大寫 strings.ToLower(name) // 轉換爲小寫
4)去除兩邊的指定字符
strings.TrimRight(name,"w") // 去除最右邊的'w' strings.TrimLeft(name,"w") // 去除最左邊的'w' strings.Trim(name,"w") // 去除左右兩邊的'w'
5)替換字符
strings.Replace(name,"w","m",1) // 在name中從左到右找到第一個w,替換爲m strings.Replace(name,"w","m",2) // 從左到右找到第二個w替換爲m strings.Replace(name,"w","m",-1) // 找到所有w替換爲m
6)分割
str1 := "192.168.1.9" result := strings.Split(str1,".") // 將str1字符串按"."分割 fmt.Println(result,reflect.TypeOf(result)) // 打印[192 168 1 9] []string
7)拼接
不建議使用"字符串"+"字符串"的形式。
dataList := []string{"我愛", "中國"} res := strings.Join(dataList, "-") fmt.Println(res) // 打印"我愛-中國"
// 建議:效率更高一點(go 1.10之前) var buffer bytes.Buffer buffer.WriteString("我想") // 加入到buffer中 buffer.WriteString("您") buffer.WriteString("喜歡中國") data:= buffer.String() // 將buffer轉換爲string fmt.Println(data)
// 建議:效果更更更高一點(go 1.10之後) var builder strings.Builder builder.WriteString("我想") // 加入到string builder中 builder.WriteString("我也") builder.WriteString("喜歡中國") value:= builder.String() // 將builder轉換爲string fmt.Println(value)
8)字符與編碼轉換
// 編碼轉字符 v1 := string(65) fmt.Println(v1) // 打印"A" v2 := string(27494) fmt.Println(v2) // 打印"武" // 字符串轉成編碼 v3,size := utf8.DecodeRuneInString("中") // 將字符"中"轉換爲編碼,以及字節長度 fmt.Println(v3,size) // 打印20013 3
9)切片和循環
mystr := "我愛北京天安門" fmt.Println(mystr[0:3]) // 取前三個字節,也就是中文"我"
// 循環獲取所有字節 for i:=0;i<len(mystr);i++ { fmt.Println(i,mystr[i]) // 打印每個index上的字節,7箇中文,一共21個字節 }
// 使用for range遍歷 for idx,item := range mystr { fmt.Println(idx,item) }
// 轉換爲rune獲取遍歷中文 runeList := []rune(mystr) for idx,item := range runeList { fmt.Println(idx,string(item)) }
七、數組
1.數組聲明
四種方式:
var numbers [3]int numbers[0] = 99 numbers[1] = 100 numbers[2] = 5
var names = [3]string{"Leo","John","Lee"}
var ages = [3]int{0:21, 2:47} // 將第一個數初始化爲21,第3個數初始化爲47
// 當聲明時賦值的話,可以省略個數 var names = [...]string{"Leo","John","Lee"} var ages = [...]int{0:21,2:47}
2.數組指針
var p_num *[3]int // 申明一個指向[3]int類型數組的指針 p_num = &[3]int{1,2,3} // 定義一個[3]int數組,將地址複製給p_num fmt.Println(*p_num) // 打印p_num指針指向的值,[1 2 3]
numbers := new([3]int) numbers[0] = 99 numbers[1] = 1 numbers[2] = 2 fmt.Println(*numbers)
3.數組內存管理
類似於C/C++:
4.數組常用功能
1)數組長度
nums := [3]int{1,2,3} fmt.Println(len(nums)) // 打印3
2)遍歷
nums := [3]int{11,22,33} for key,item := range nums { fmt.Println(key,item) }
nums := [3]int{11,22,33} for _,item := range nums { fmt.Println(item) // 不需要idx的時候,可以用"_" }
3)數組的嵌套
var data [2][3]int // 聲明一個二維數組 data[0] = [3]int{1,2,3} data[1] = [3]int{4,5,6} fmt.Println(data) // 打印[[1 2 3] [4 5 6]]
var data *[2][3]int data = &[2][3]int{{1,2,3},{4,5,6}} fmt.Println(data)