一.變量常量
1.變量定義
package main
import "fmt"
// 聲明文件所在包 每個go文件必須有歸屬包
// go build test.go 編譯 -o hello.exe 指定編譯后文件名
// go run test.go 編譯執(zhí)行
// gofmt -w test.go 格式話操作
/*
源文件以 go 為擴(kuò)展名
程序的執(zhí)行入口是main()函數(shù)
嚴(yán)格區(qū)分大小寫
方法由一條條語句構(gòu)成 每個語句后不需要分號(go語言會在每行后自動加分號)
go編譯器是一行行進(jìn)行編譯的杯巨,因此我們一行就寫一條語句
定義的變量或者import的包如果沒有使用到每聪,代碼不能編譯通過
大括號都是成對出現(xiàn)的
*/
// 全家變量定義 可以一次性聲明
var a1 = 100
var a2 = 0.01
var (
a3 = 500
a4 = "xxx"
)
func main() {
fmt.Println("He"+"llo", "Hello") // Hello Hello
var age1 int // 變量聲明方式1 指定類型 賦值 var age int = 20
age1 = 19
var age2 int // 變量聲明方式2 指定類型 不賦值 默認(rèn)值
var age3 = 21 // 變量聲明方式3 沒有寫變量類型 自動類型推斷
age4 := 22 // 變量聲明方式4 省略var 用:=
fmt.Println("age = ", age1, age2, age3, age4)
//支持多變量聲明
var n1, n2, n3 int
fmt.Println(n1, n2, n3)
var n4, n5, n6 = "10", 0.1, 10
fmt.Println(n4, n5, n6)
fmt.Println(a1, a2, a3, a4)
}
Go 中的 全局變量比較特殊,如果全局變量首字母小寫疲眷,則只能別當(dāng)前包中的go文件使用禾蚕,外部無法使用;
如果首字母大寫狂丝,則任意文件都可以使用全局變量
2.匿名變量_
不占用命名空間换淆,不會分配內(nèi)存,所以匿名變量之間不存在重復(fù)聲明
package main
func getUserinfo() (string, int) {
return "zhang", 19
}
func main() {
var username, _ = getUserinfo() // _ 匿名變量
println(username) // zhang
}
3.常量const
常量值無法改變
func main() {
const pi = 3.14 // 定義常量
fmt.Println(pi)
const ( // 定義多個常量
A = "A"
B = "B"
C // 省略值表示和上一行值相同
)
// const a, b, c = 1, 2, 3 // 定義多個常量
fmt.Println(A, B, C) // A B B
}
iota常量計數(shù)器
package main
import "fmt"
func main() {
const (
n1 = iota // 第一個值是iota几颜,后面值累加
n2
_ // 跳過
n3
)
fmt.Println(n1, n2, n3) // 0 1 3
}
多iota定義一行
package main
import "fmt"
func main() {
const (
n1, c1 = iota + 1, iota + 2
n2, c2
n3, c3
)
fmt.Println(n1, n2, n3) // 1 2 3
fmt.Println(c1, c2, c3) // 2 3 4
}
二.基本數(shù)據(jù)類型
1.整數(shù)類型
類型 | 有無符號 | 占用存儲空間 | 表數(shù)范圍 |
---|---|---|---|
int8 | 有 | 1字節(jié) | -128 ~ 127 |
int16 | 有 | 2字節(jié) | -32768 ~ 32767 |
int32 | 有 | 4字節(jié) | -2^31 ~ 2^31-1 |
int64 | 有 | 8字節(jié) | -2^63 ~ 2^63-1 -2147483648~2147483647 |
uint8 | 無 | 1字節(jié) | 0 ~ 255 |
uint16 | 無 | 2字節(jié) | 0 ~ 65535 |
uint32 | 無 | 4字節(jié) | 0 ~ 2^31-1 0~4294967295 |
uint64 | 無 | 8字節(jié) | 0 ~ 2^63-1 |
類型 | |
---|---|
int | 在32位系統(tǒng)相對于int32倍试,在64位系統(tǒng)相當(dāng)于int64 |
uint | 在32位系統(tǒng)相對于uint32,在64位系統(tǒng)相當(dāng)于uint64 |
runne | 等價于 int32 |
byte | 等價于 uint8 |
整數(shù)類型默認(rèn)是int 蛋哭,超出邊界報錯
package main
import "fmt"
var num = 28
func main() {
fmt.Printf("num類型是: %T", num) // num類型是: int
fmt.Println()
fmt.Println(unsafe.Sizeof(num)) // 變量占用字節(jié)數(shù) 8
}
類型轉(zhuǎn)換
import "fmt"
var n1 int8 = 10
var n2 int16 = 20
func main() {
fmt.Println(int16(n1) + n2) // 把n1轉(zhuǎn)換int16 進(jìn)行計算
var n3 int64 = 888 // 將int64轉(zhuǎn)為int8的時候县习,編譯不會出錯的,但是會數(shù)據(jù)的溢出
var n4 int8 = int8(n3)
fmt.Println(n4) //120
}
2.浮點型
類型 | 占用存儲空間 | 表數(shù)范圍 |
---|---|---|
float32 | 4字節(jié) | -3.403E38~3.403E38 |
float64 | 8字節(jié) | -1.798E308~1.798E308 |
浮點類型底層存儲:符號位+指數(shù)位+尾數(shù)位谆趾,所以尾數(shù)位只是存了 一個大概躁愿,很可能會出現(xiàn)精度的損失。
float32的精度只能提供大約6個十進(jìn)制數(shù)(表示后科學(xué)計數(shù)法后沪蓬,小數(shù)點后6位)的精度
float64的精度能提供大約15個十進(jìn)制數(shù)(表示后科學(xué)計數(shù)法后彤钟,小數(shù)點后15位)的精度
float64精度更高,通常使用float64跷叉,默認(rèn)浮點類型是float64
var num = 3.14
fmt.Println(num)
package main
import "fmt"
func main() {
var num1 float32 = 3.14
fmt.Println(num1) // 3.14
var num2 float32 = -3.14
fmt.Println(num2) // -3.14
var num3 float32 = -314e-2 // e-2是科學(xué)計數(shù)法 10的-2次方
fmt.Println(num3) // -3.14
var num4 float32 = 314e+2 // e+2是科學(xué)計數(shù)法 10的2次方
fmt.Println(num4) // 31400
var num5 float32 = 1.000000916
fmt.Println(num5) // 1.000001
var num6 float64 = 1.000000916
fmt.Println(num6) // 1.000000916
}
格式化輸出
package main
import "fmt"
func main() {
var n1 float32 = 3.1415926
fmt.Println(n1) // 3.1415925
fmt.Printf("%v %f %T\n", n1, n1, n1) // 3.1415925 3.141593 float32 %v 原樣輸出 %f默認(rèn)保留六位小數(shù)點
fmt.Printf("%.2f\n", n1) // %.2f 輸出數(shù)據(jù)的時候保留2位小數(shù)
}
float精度丟失
package main
import "fmt"
func main() {
var n1 float64 = 1129.6
fmt.Println(n1 * 100) // 112959.99999999999
m1, m2 := 8.2, 3.8
fmt.Println(m1 - m2) // 4.3999999999999995
}
decimal精度小數(shù)
package main
import (
"fmt"
"github.com/shopspring/decimal"
)
func main(){
var num1 float64 = 3.1
var num2 float64 = 4.2
d1 := decimal.NewFromFloat(num1).Add(decimal.NewFromFloat(num2))
fmt.Println(d1)//7.3
}
3.布爾類型
布爾類型占1個字節(jié),默認(rèn)false
無法參與運算逸雹,也無法與其他類型轉(zhuǎn)換
package main
import "fmt"
func main() {
var flag bool = 5 < 9
fmt.Println(flag)
}
4.字符串類型
默認(rèn)為空 ""
轉(zhuǎn)義字符
轉(zhuǎn)義符 | 含義 | unicode值 |
---|---|---|
\b | 退格 | \u0008 |
\n | 換行 | \u000a |
\r | 回車 | \u000d |
\t | 制表符 tab | \u0009 |
\" | 雙引號 | \u0022 |
' | 單引號 | \u0027 |
\ | 反斜桿 | \u005c |
package main
import "fmt"
func main() {
var s1 string = "這個\"字符串" // 字符串是不可變的:指的是字符串一旦定義好,其中的字符的值不能改變
var s2 = `這個"字符串` // 有特殊字符性芬,可以用反引號 `峡眶,反引號還可以定義多行
s3 := "abc" + "ABC" // 字符串拼接 當(dāng)一個字符串過長的時候:注意:+保留在上一行的最后
fmt.Println(s1, s2, s3) // 這個"字符串 這個"字符串 abcABC=
}
strconve函數(shù)基本數(shù)據(jù)類型轉(zhuǎn)string
package main
import(
"fmt"
"strconv"
)
func main(){
var n1 int = 18
var s1 string = strconv.FormatInt(int64(n1),10) //參數(shù):第一個參數(shù)必須轉(zhuǎn)為int64類型 ,第二個參數(shù)指定字面值的進(jìn)制形式為十進(jìn)制
fmt.Printf("s1對應(yīng)的類型是:%T 植锉,s1 = %q \n",s1, s1)
var n2 float64 = 4.29
var s2 string = strconv.FormatFloat(n2,'f',9,64)
//第二個參數(shù):'f'(-ddd.dddd) 第三個參數(shù):9 保留小數(shù)點后面9位 第四個參數(shù):表示這個小數(shù)是float64類型
fmt.Printf("s2對應(yīng)的類型是:%T 辫樱,s2 = %q \n",s2, s2)
var n3 bool = true
var s3 string = strconv.FormatBool(n3)
fmt.Printf("s3對應(yīng)的類型是:%T ,s3 = %q \n",s3, s3)
}
s1對應(yīng)的類型是:string 俊庇,s1 = "18"
s2對應(yīng)的類型是:string 狮暑,s2 = "4.290000000"
s3對應(yīng)的類型是:string 鸡挠,s3 = "true"
strconve函數(shù)string轉(zhuǎn)基本數(shù)據(jù)類型
package main
import(
"fmt"
"strconv"
)
func main(){
//string-->bool
var s1 string = "true"
var b bool
//ParseBool這個函數(shù)的返回值有兩個:(value bool, err error)
//value就是我們得到的布爾類型的數(shù)據(jù),err出現(xiàn)的錯誤
//我們只關(guān)注得到的布爾類型的數(shù)據(jù)搬男,err可以用_直接忽略
b , _ = strconv.ParseBool(s1)
fmt.Printf("b的類型是:%T,b=%v \n",b,b) // b的類型是:bool,b=true
//string---> int64
var s2 string = "19"
var num1 int64
num1,_ = strconv.ParseInt(s2,10,64) // 10 指定進(jìn)制 int64
fmt.Printf("num1的類型是:%T,num1=%v \n",num1,num1) // num1的類型是:int64,num1=19
//string-->float32/float64
var s3 string = "3.14"
var f1 float64
f1,_ = strconv.ParseFloat(s3,64)
fmt.Printf("f1的類型是:%T,f1=%v \n",f1,f1) // f1的類型是:float64,f1=3.14
//注意:string向基本數(shù)據(jù)類型轉(zhuǎn)換的時候拣展,一定要確保string類型能夠轉(zhuǎn)成有效的數(shù)據(jù)類型,否則最后得到的結(jié)果就是按照對應(yīng)類型的默認(rèn)值輸出
var s4 string = "golang"
var b1 bool
b1 , _ = strconv.ParseBool(s4)
fmt.Printf("b1的類型是:%T,b1=%v \n",b1,b1) // b1的類型是:bool,b1=false
var s5 string = "golang"
var num2 int64
num2,_ = strconv.ParseInt(s5,10,64)
fmt.Printf("num2的類型是:%T,num2=%v \n",num2,num2) // num2的類型是:int64,num2=0
}
字符串函數(shù)
// 1. len(str) 統(tǒng)計字符串長度缔逛,按字節(jié)統(tǒng)計
str := "golang你好" // 漢字是utf8字符集备埃,一個漢字3個字節(jié)
fmt.Println(len(str)) // 12字節(jié) 不能用unsafe.Sizeof()
// 2. for range 字符串遍歷
for i, value := range str { // 利用鍵值循環(huán)
fmt.Printf("索引 %d 值 %c \n",i, value)
}
索引 0 值 g
索引 1 值 o
索引 2 值 l
索引 3 值 a
索引 4 值 n
索引 5 值 g
索引 6 值 你
索引 9 值 好
// 3. strconv.Atoi()字符串轉(zhuǎn)整數(shù)
num1,_ := strconv.Atoi("66")
fmt.Printf("%T \n",num1) // int
// 4. strconv.Itoa()整數(shù)轉(zhuǎn)字符串
str1,_ := strconv.Itoa(66)
fmt.Printf("%T \n",str1)
// 5. strings.Contains()查找子串是否在指定的字符串中
package main
import "fmt"
import "strings"
func main(){
fmt.Println(strings.Contains("golang","go")) // true
}
// 6. strings.Count()統(tǒng)計一個字符串有幾個指定的子串
fmt.Println(strings.Count("golang","go")) // 1
// 7. strings.EqualFold()不區(qū)分大小寫的字符串比較
fmt.Println(strings.EqualFold("go" , "Go")) // true
// 8. strings.lndex()返回子串在字符串第一次出現(xiàn)的索引值,如果沒有返回-1
fmt.Println(strings.Index("golang" , "an")) // 3
// 9. strings.Replace()字符串的替換 -1表示全部替換
fmt.Println(strings.Replace("golang", "g", "G", -1)) // GolanG
// 10. 按照指定的某個字符褐奴,為分割標(biāo)識按脚,將一個學(xué)符串拆分成字符串?dāng)?shù)組
fmt.Println(strings.Split("go-python-java", "-")) // [go python java]
// 11. 將字符串的字母進(jìn)行大小寫的轉(zhuǎn)換
fmt.Println(strings.Split(strings.ToLower("Go")) // go
fmt.Println(strings.Split(strings.ToUpper"go")) //Go
// 12. strings.TrimSpace()將字符串左右兩邊的空格去掉
fmt.Println(strings.TrimSpace(" golang "))
// 13. strings.Trim()將字符串左右兩邊指定的字符去掉
fmt.Println(strings.Trim("~golang~ ", " ~"))
// 14. strings.TrimLeft()將字符串左邊指定的字符去掉
fmt.Println(strings.TrimLeft("~golang~", "~")) // golang~
// 15. strings.TrimRight()將字符串右邊指定的字符去掉
fmt.Println(strings.TrimRight("~golang~", "~")) // ~golang
// 16. strings.HasPrefix()判斷字符串是否以指定的字符串開頭
fmt.Println(strings.HasPrefix("golang", "go")) // true
// 17. strings.HasSuffix()判斷字符串是否以指定的字符串結(jié)束
fmt.Println(strings.HasSuffix("golang", "ng")) // true
5.字符類型
Golang中沒有專門的字符類型,如果要存儲單個字符(字母)敦冬,一般使用byte來保存辅搬。
Golang中字符使用UTF-8編碼(Unicode是對應(yīng)的字符集,UTF-8是Unicode的其中的一種編碼方案)
package main
import "fmt"
func main() {
var n = '中'
fmt.Printf("%v,%T", n, n) // 20013,int32 碼值 20013
}
三.復(fù)合數(shù)據(jù)類型
數(shù)組 切片 結(jié)構(gòu)體 函數(shù) map 通道(channel) 接口