分類
Go語(yǔ)言中的數(shù)據(jù)類型分為:基本數(shù)據(jù)類型和復(fù)合數(shù)據(jù)類型
- 基本數(shù)據(jù)類型
整型、浮點(diǎn)型、布爾型羊苟、字符串
- 復(fù)合數(shù)據(jù)類型
數(shù)組、切片哎迄、結(jié)構(gòu)體、函數(shù)隆圆、map漱挚、通道(channel)、接口等
整型
整型分為以下兩個(gè)大類:
- 有符號(hào)整型按長(zhǎng)度分:int8渺氧、int16旨涝、int32、int64
- 對(duì)應(yīng)的無符號(hào)整型:uint8侣背、uint16白华、uint32、uint64
- 定義int類型
默認(rèn)值為空
var num int = 10
fmt.Printf("num=%v 類型:%T",num, num)
//num=10 類型:int
默認(rèn)的int類型長(zhǎng)度跟隨操作系統(tǒng)32/64位而變化
類型 | 范圍 | 占用空間 |
---|---|---|
int8 | -127~128 | 1B |
int16 | -32768~32767 | 2B |
int32 | -231~231-1 | 4B |
int64 | -263~263-1 | 8B |
- 不同長(zhǎng)度的int之間的轉(zhuǎn)換
var a1 int32 = 10
var a2 int64 = 21
fmt.Println(a1 + a2)
//報(bào)錯(cuò)贩耐,int32和int64為不同類型弧腥,不能直接參與運(yùn)算
fmt.Println(int64(a1) + a2)
高位向底位轉(zhuǎn)換時(shí)是直接截取,要注意數(shù)值符號(hào)
byte和rune類型
- uint8類型潮太,或者叫byte型管搪,代表了ASCII的一個(gè)字符
- rune類型,代表一個(gè)UTF-8字符铡买。當(dāng)需要處理中文更鲁、日文或其他復(fù)合字符時(shí),需要用到rune類型寻狂。rune類型實(shí)際是一個(gè)int32
var a = 'a'
fmt.Printf("值:%v 類型:%T")
//值:97 類型:int32
fmt.Printf("值:%v 類型:%T")
//值:a 類型:int32
在Go中一個(gè)字母占用1個(gè)字節(jié)岁经,一個(gè)漢字占用3個(gè)字節(jié)(utf-8編碼)
var str = "this"
fmt.Println(unsafe.Sizeof(str), len(str))
//16 4
這里不管
str
的內(nèi)容是多少朋沮,Sizeof
始終打印16
蛇券,與他的內(nèi)存結(jié)構(gòu)有關(guān);要查看他真實(shí)長(zhǎng)度的時(shí)候樊拓,可以用len()
方法
Sizeof
查看不同的數(shù)據(jù)類型纠亚,在內(nèi)存中占用的存儲(chǔ)空間(無法查看string類型)
var num int8 = 15
fmt.Println(unsafe.Sizeof(num))
//1
浮點(diǎn)型(與C基本相同)
Go支持兩種浮點(diǎn)數(shù):float32和float64,四舍五入保留6位小數(shù)筋夏,分別占用4B和8B
var num float32 = 3.12
fmt.Println(unsafe.Sizeof(num))//4
var c float64 = 3.14159255
fmt.Printf("%v-%f", c, c)
//3.14159255-3.141592
fmt.Printf("%.2f")
//保留兩位小數(shù)3.14
Go語(yǔ)言中默認(rèn)浮點(diǎn)數(shù)為float64
- 科學(xué)計(jì)數(shù)法表示浮點(diǎn)類型
3.14e 表示3.14*102
- float精度丟失問題
幾乎所有的編程語(yǔ)言都有精度丟失的問題蒂胞,這是典型的二進(jìn)制浮點(diǎn)數(shù)精度損失問題。在定長(zhǎng)條件下条篷,二進(jìn)制小數(shù)和十進(jìn)制小數(shù)互轉(zhuǎn)可能有精度丟失骗随。
var num float64 = 1129.6
fmt.Println(num*100)
//112529.9999999999
可以使用第三方包來解決精度損失問題
https://github.com/shopspring/decimal
import(
"fmt"
"github.com/shopspring/decimal"
)
func main(){
m1 := 8.2
m2 := 3.8
res := decimal.NewFromFloat(m1).Sub(decimal.NewFromFloat(m2))
fmt.Println(res)
}
- int與float之間的轉(zhuǎn)換
int => float
a := 10
b := float64(a)
fmt.Printf("a的類型是%T,b的類型是%T", a, b)
//a的類型是int,b的類型是float
var a1 float32 = 23.4
a2 := float64(a1)
//a1是float32蛤织,a2是float64
float => int會(huì)直接截取,丟失數(shù)據(jù)(不建議)
布爾型數(shù)據(jù)
- 布爾型變量默認(rèn)為false
- Go語(yǔ)言中不允許將整型強(qiáng)制轉(zhuǎn)換為布爾型
- 布爾型無法參與數(shù)值運(yùn)算鸿染,也無法與其他類型轉(zhuǎn)換
字符串
默認(rèn)值為空指蚜,用雙引號(hào)
""
包裹值
- 字符串轉(zhuǎn)義字符
轉(zhuǎn)義符 | 含義 |
---|---|
\r |
回車符(返回行首) |
\n |
換行符(直接跳到下一行的同列位置) |
\t |
制表符 |
\' |
單引號(hào) |
\" |
雙引號(hào) |
\\ |
反斜杠 |
- 多行字符串(JS中ES6的模板字符串)
str := `this
is
str
`
fmt.Println(str)
- 字符串的常用操作
方法 | 說明 |
---|---|
len(str) | 求長(zhǎng)度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判斷是否包含 |
strings.HasPrefix, strings, HasSuffix | 前綴/后綴判斷 |
strings.Index(), strings.LastIndex() | 子串出現(xiàn)的位置 |
strings.Join(a[]string, sep string) | 切片轉(zhuǎn)字符串 |
var str1 = "aaa"
var str2 = "哈嘍"
var str3 = "123-456-789"
fmt.Println(len(str1), len(str2))//4 6
fmt.Sprintf("%v %v", str1, str2)//aaa 哈嘍
arr := strings.Split(str,"-")
fmt.Println(arr)//切片[123 456 789]
fmt.Println(strings.Join(arr, "-"))//123-456-789
newArr := []string{"php","JavaScript","golang"}
fmt.Pringln(string.Join(newArr))//[php JavaScript golang]
str10 := "this is str"
str11 := "this"
flag := strings.Contains(str10, str11)
//判斷str10中是否包含true
fmt.Println("strings.HasPrefix(str10, str11)")//判斷str1是否以str2開頭
fmt.Println("strings.HasSuffix(str10, str11)")//判斷str2是否以str2結(jié)尾
fmt.Println(strings.Index(str10, str11))
//判斷str11在str10中首次出現(xiàn)的位置 0
fmt.Println(strings.LastIndex(str10, "is"))
//判斷str11在str10中最后出現(xiàn)的位置(位置始終按照從左往右計(jì)算)5
- 循環(huán)遍歷字符串
s := "hello"
for i :=0; i < len(s); i++ {//byte
fmt.Printf("%v(%c)", s[i], s[i])
}
fmt.Println()
//打印有問題,因?yàn)橐粋€(gè)漢字占用了3個(gè)字節(jié)
for _,r := range s {//rune
fmt.Printf("%v(%c)", r, r)
}
- 修改字符串
要修改字符串涨椒,需要先將其轉(zhuǎn)換成[]rune或[]byte摊鸡,完成后再轉(zhuǎn)換為string。無論哪種轉(zhuǎn)換蚕冬,都會(huì)重新分配內(nèi)存免猾,并復(fù)制字節(jié)數(shù)組。
s1 := "big"
byteS1 := []byte(s1)
byteS1[0] = "p"
fmt.Println(string(byteS1))//pig
s2 := "胡蘿卜"
runeS2 := []rune(s2)
runeS2[0] = '白'
fmt.Println(string(runeS2))//白蘿卜
- sprintf
string=>other. sprintf使用中需要注意轉(zhuǎn)換的格式
int為%d float為%f bool為%t byte為%c
var i int = 20
var f float64 = 12.456
var t tool = true
var b byte = 'a'
str := fmt.Sprintf("%d", i)
fmt.Printf("%v%T", str, str)//20string
str2 := fmt.Sprintf("%.2f", f)
fmt.Printf("%v%T", str2, str2)//12.46string
str3 := fmt.Sprintf("t", f)
fmt.Printf("%v %T", str3, str3)//true string
str4 := fmt.Sprintf("%c", b)
fmt.Printf("%v %T")//a string
- ParseInt(string數(shù)據(jù),進(jìn)制囤热,位數(shù))
ParseInt方法有兩個(gè)返回值猎提,一個(gè)是轉(zhuǎn)換的結(jié)果,一個(gè)是返回的錯(cuò)誤信息
str := "123456"
fmt.Printf("%v%T\n", str, str)
num, _ := strconv.ParseInt(str, 10, 64)
fmt.Printf("%v%T",num, num)//123456 int64
- ParseFloat(string數(shù)據(jù),位數(shù))
str := 123.456
num, _ := strconv.ParseFloat(str, 64)//123.456 float64
- strconv包
其他類型轉(zhuǎn)string類型
1.int=>string: 該方法中接收兩個(gè)參數(shù)旁蔼,參數(shù)1:int64的數(shù)值忧侧;參數(shù)2:當(dāng)前int類型的進(jìn)制
var i int = 20
str1 := strconv.FormatInt(int64(i), 10)
fmt.Printf("%v%T", str1, str1)//20string
var f float = 20.32
str2 := strconf.FormatFloat
- float=>string: 接收四個(gè)參數(shù)
參數(shù)1:傳入的值;
參數(shù)2:格式化的方式 'f'(-ddd.dddd)……牌芋;
參數(shù)3:保留的小數(shù)點(diǎn)(-1表示不對(duì)小數(shù)點(diǎn)格式化)蚓炬;
參數(shù)4:格式化的類型(傳入64/32)
var f float32 = 3.141592
str := strconv.FormatFloat(float64(f), 'f', 4, 64)
fmt.Printf("%v%T", str, str)//3.1416 string
- bool=>string
str := strconv.FormatBool(true)
fmt.Printf("%v%T", str, str)//true string
數(shù)值型無法和bool類型轉(zhuǎn)換
- 字符=>string
a := 'b'
str := strconv.FormatUint(uint64(a), 10)
fmt.Printf("%v%T", str, str)//98 string
自定義類型和類型別名
//自定義類型
type myInt int
//類型別名
type myFloat = float64
func main(){
var a myInt = 10
fmt.Printf("%v %T", a, a) //10 main.myInt
var b myFloat = 123.4
fmt.Printf("%v %T", b, b) //123.4 float64
}