基本語法:包、函數、var變量、const常量、類型、流程控制、更多類型
包管理
go中沒有public、private、protected等訪問控制修飾符,它是通過字母大小表示能否被其他方訪問或者調用的,大寫的方法就表示是可以被調用的(相當於public),小寫就只能在包內用。public與否的另一種說法是“是否導出”, 對應的,大寫的表示是已導出的,小寫開頭的表示是未導出的,所以當你調用別的包裏的方法就永遠都是大寫開始的fmt.PrintIn(math.pi)
另外,go的包名只需要寫短的就行,它會根據放在哪個文件夾的路徑下面去自動推導的
函數
func
關鍵字,add
函數名,(x, y int)
參數及其類型,當參數類型相同可以只用一個類型(類型聲明是放後面的), 最後一個int
表示返回類型
func add(x, y int) int{
return x+y;
}
函數特點:
1,可以多值返回
func swap(x, y string)(string string)
{
return y,x
}
2,可以對返回值進行命名(但感覺可讀性不是很好,代碼多了容易看暈……
func split(sum int)(x, y int)
{
x = sum * 4 / 9
y = sum - x
return
}
變量
特點:
1,變量可以出現在包的級別,也可以出現在func中
2,可以一起初始化,可以不指定類型var java, c, test = 1, "dfer", true
package main
import "fmt"
var i, j int = 1,2 //可以在包內出現,可以指明類型
func main()
{
var c, python, java = true, false, "ok" //可以出現在函數內,可以不指明類型
fmt.Println(i, j, c, python, java)
}
3,簡潔賦值語句 :=
可在類型明確的地方代替var聲明,但不能出現在函數外
package main
import "fmt"
func main()
{
var i, j, int = 1, 2 //var的用法,要寫變量,可能要聲明,要賦值,太麻煩
k := 3 //就是上行賦值前的縮寫
c, python, java := true, false, "ok" //多個賦值也可以
fmt.Println(i, j, k, c, python, java)
}
const 常量
類型
注意沒有float
,一般就用float64
, int……
那一類我們一般就直接用int
, byte
相當於無符號八位整型uint8
, rune
用比較少相當於int32
表示一個unicode碼點(?)
類型自動推導
就是在初始化一個變量的時候,直接給它一個值,系統就會自動根據這個值來判斷類型
類型轉換
在Go中,不同類型的項之間賦值時需要顯示轉換,不支持隱式轉換
數值之間的轉換比較簡單:
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
或者更加簡單的形式
i := 42
f := float64(i)
u := uint(f)
string和int…之間的轉換稍微麻煩一點
int, err := strconv.Atoi(str) //string轉換成int
string := strconv.Itoa(int) //int ->string
var data []byte = []byte(str) //str->byte
var str string = string(data[:]) //byte->string
//float<--> strinf
float, err:=strconv.ParseFloat()
string = strconv.Format()
Go的流程控制
1, 只有一種循環結構for 賦初值; 終止條件; 每次循環之後對變量的操作
不需要括號, 其中第一個和第三個條件是可以去掉的,可以連着分號去掉,這個時候跟while
語句沒什麼區別了
func mian()
{
//sum :=1
for sun := 1; sum <1000; sum +=1
{
sum+=sum
}
fmt.Println(sum)
}
for{}
就是一個死循環
2, if else 區別在於可以在執行判斷前先執行一個語句if z:=x+y; z<a{}
其實我們要做的判斷是z<a
但是在做這個判斷前先做一個操作
3,switch:特點是Go只運行選定的case,而非之後所有的case,相當於在每個case後面自動提供了一個break
,除非以fallthrough
語句結束,否則分支會自動終止; 而且Go的另一重要點在於switch的case無需爲常量,且不必取爲整數
另外,也可以在執行前,先執行一個語句switch v:=x+y; v{}
在做判斷之前可以做一個類似於初始化的操作
func main()
{
fmt.Print("Go runs on")
switch os:= runtime.GOOS; os
{
case "darwin" :
fmt.Println("Os X")
case "linux"
fmt.Println("Linux")
default:
//...
fmt.Println("%s. \n", os)
}
}
最後,可以用switch(無判斷)+case 替代一堆if else
func main()
{
t := time.Now()
switch //沒有判斷
{
case t.Hour() <12
fmt. Println("Good morning")
case t.Hor()<17
fmt. Println("afternoon")
default:
fmt.Println("evening")
}
}
5, defer
1,defer語句會推遲到外層函數返回之後執行,但其參數會立即求值,只是返回前不會調用
2,defer的調用是被壓入了棧中,會按先進後出的順序調用
延時執行
func add1(x int) int
{
fmt.Println("add1")
return x+1
}
func main()
{
defer fmt.Println("world", add1(8))
fmt.Println("hello")
}
main函數運行到defer先不執行打印語句,但是會將參數add1先求出來但是不去調用,等全部執行完再去執行defer語句