
0.基本語(yǔ)法結(jié)構(gòu)
package main
import "fmt"
func main(){
fmt.Println("Hello World")
}
- 聲明包
- 保留了大括號(hào),但去掉了分號(hào)
- 和python有點(diǎn)像,但沒(méi)有強(qiáng)制鎖進(jìn)
- 首字母大寫(xiě)表示public,小寫(xiě)表示private
- 和類(lèi)c語(yǔ)言相似,都是從main函數(shù)開(kāi)始執(zhí)行
1、 變量
變量的聲明和初始化
go語(yǔ)言的變量聲明需要使用var一下,或者使用海象運(yùn)算符
var x int =1 //長(zhǎng)聲明
var y,z int =1024,2048 //多重聲明
p:=3 //海象運(yùn)算符,短聲明
//如果沒(méi)有初始化,用默認(rèn)值代替
const Pi=3.14 //常量,變量不可更改。聲明常量需要關(guān)鍵字const,禁止使用海象運(yùn)算符
變量類(lèi)型
go是強(qiáng)類(lèi)型語(yǔ)言,對(duì)于數(shù)值類(lèi)型的定義域和符號(hào)分的很清,除了所有語(yǔ)言都有的數(shù)字類(lèi)型、字符串、數(shù)組外,還有一些go獨(dú)有的派生類(lèi)型。
整數(shù)類(lèi)型:int,int8,int32,int64,帶符號(hào)和不帶符號(hào)
浮點(diǎn)類(lèi)型:Float32—單精度浮點(diǎn)值,F(xiàn)loat64—雙精度浮點(diǎn)值
布爾類(lèi)型:true,false
字符串類(lèi)型:string
數(shù)組類(lèi)型:array
指針類(lèi)型:pointer
管道類(lèi)型:chan
接口類(lèi)型:interface
常量
const PI =3.1415926
2 、運(yùn)算符
//算術(shù)運(yùn)算符
x,y :=1,2
res:=x+y //加法
res:=x-y //減法
res:=x/y //除法,取整
res:=x%y //模,取余數(shù)
res+=x //賦值運(yùn)算符,類(lèi)似的*=,%=
//關(guān)系運(yùn)算符
res:=x==y
res:=x!=y
res:=x>y
res:=x<y
//邏輯運(yùn)算符
res:=x>0&&y>=0 //與門(mén)
res:=x>0||y>0 //或門(mén)
res:=!(x>y)//非門(mén)
3、 邏輯結(jié)構(gòu)
判斷
//判斷語(yǔ)句
x:=1
if x>0{
//... ...
}else{
//... ...
}
循環(huán)
//for循環(huán)
for x:=1;x<10;x++{
//...
}
// 省略初始化和迭代loop
x:=1
for x<10{
//...
x++
}
switch
//switch,注意go中沒(méi)有break語(yǔ)句,遇到第一個(gè)匹配的case就會(huì)跳出判斷,不會(huì)穿透
x:=1
switch x{
case 1:
//...
case 2:
//...
case 3:
//...
default:
//...
}
4、函數(shù)
函數(shù)結(jié)構(gòu)
關(guān)鍵字、函數(shù)名、函數(shù)體、輸入?yún)?shù),返回值
//基本結(jié)構(gòu),關(guān)鍵字、函數(shù)名、函數(shù)體、形參、返回值
func FunName(v int) string{
return st
}
//多個(gè)參數(shù)的輸入和輸出
func FunName(v1 int ,v2 int)(int,string){
return 2,"2"
}
可變參數(shù)
// 例子:求n個(gè)整數(shù)的和
func sum(x ...int) (s int) {
//可變參數(shù)
for _, v := range x {
s += v
}
return
}
// 也可以直接把切片扔進(jìn)去作為可變參數(shù)
arr=[3]int{1,2,3}
sum(arr...) //類(lèi)似于解包的操作
閉包于匿名函數(shù)
閉包給了在內(nèi)部函數(shù)捕獲外部函數(shù)參數(shù)的權(quán)利,匿名函數(shù)是閉包的實(shí)現(xiàn)方式之一,字面意思上的沒(méi)有名字,直接調(diào)用的函數(shù)。
// 函數(shù)的閉包
func test14(a int, b int) int {
func() {
fmt.Println(a, b)
}()
return a + b
}
5、指針
指針,即一個(gè)值的內(nèi)存地址。在go中,&表示取地址,*表示取值。
指針聲明
var p1 *int
var p2 *string
// go中指針必須帶類(lèi)型
6、結(jié)構(gòu)體
定義數(shù)據(jù)使用,類(lèi)似于其他面向?qū)ο笳Z(yǔ)言中的class
type Contact struct{
Age int
Name string
}
結(jié)構(gòu)體與指針
x:=&Contact{"ronron",12}
x.name="xiaojiji"
7、方法
結(jié)構(gòu)體除了聲明了屬性外,還能定義方法,方法即帶接收器的函數(shù)。
type Contact struct{
Name string
Age int
}
// 方法,結(jié)構(gòu)體接收器
func (c Constact) addAge1(){
c.Age+=1
}
// 方法,結(jié)構(gòu)體指針接收器
func (c *Contact) addAge2(){
c.Age+=1
}
與普通函數(shù)相比,方法多了一個(gè)接收器,這個(gè)接收器可以是結(jié)構(gòu)體,也可以是結(jié)構(gòu)體指針。如果是結(jié)構(gòu)體,那么傳遞的是結(jié)構(gòu)體副本,修改不會(huì)影響原有的對(duì)象。如果是結(jié)構(gòu)體指針,那么會(huì)影響原有的對(duì)象。
8、數(shù)組 Array
var a [3]int //定義一個(gè)長(zhǎng)度為3的空數(shù)組
var a [3]int{1,2,3} //定義一個(gè)長(zhǎng)度為3的數(shù)組并初始化
//數(shù)組的操作
// 索引
a[1]
數(shù)組一旦定義就無(wú)法修改大小,不方便使用,所以常用切片 slice代替
//切片定義方式一,直接從數(shù)組中切下來(lái)
a :=[5]int{1,2,3,4,5}
b:=a[1,3]
//切片定義方式二 ,使用make方法
c:=make([]int,5,10) //注意初始化長(zhǎng)度為5,元素默認(rèn)為0
//切片的遍歷,和python真的相似
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
for _, v := range a {
fmt.Println(v)
}
切片
go語(yǔ)言中的數(shù)組一旦定義就不能再改變長(zhǎng)度,不大好用。切片是數(shù)組的高一級(jí)別的抽象,可以理解為動(dòng)態(tài)數(shù)組。
// 定義一個(gè)字符串的切片,初始長(zhǎng)度為10,容量為20
s:=make([]string 10,20)
// 切片的索引,與python相似
s[1:3]
//
9、字典Map
//直接定義和初始化map
m := map[string]int{
"a": 1,
"b": 2,
}
// 使用make進(jìn)行初始化
m :=make(map[string]int)
// 添加元素
m["c"]=1024
//獲取value
value,ok:=m["c"]
value,ok:=m["d"]
if ok{
}else{
}
//遍歷map
for k, v := range m {
fmt.Println(k, v)
}
//刪除dict元素
delete(m,"a")
10、并發(fā)
并發(fā)是go語(yǔ)言提供的核心語(yǔ)法,相比其他語(yǔ)言多線(xiàn)程的方式,使用簡(jiǎn)單,效率更高,管理便捷。
go例程中最核心的概念是goroutine和chan
goroutine
// 任務(wù)1
func A(){
//do some thing a
}
//任務(wù)2
func B(){
// do some thing b
}
//關(guān)鍵字go 直接使用例程,類(lèi)似于其他語(yǔ)言中開(kāi)辟一個(gè)新的線(xiàn)程
func main(){
go A() //處理任務(wù)A
go B() //處理任務(wù)B
}
channel
Channel用于多個(gè)goroutine 之間進(jìn)行通信,<-符合指示數(shù)據(jù)的流動(dòng)方向
// 創(chuàng)建一個(gè)channel
ch:=make(chan int)
// 向chan中發(fā)射數(shù)據(jù)
ch <- 1
// 從chan中接受一個(gè)數(shù)據(jù)
value := <-chan
// 不用變量接收也可以
<- chan
11 錯(cuò)誤處理
go中沒(méi)有exception的概念,取而代之的是error,error在go中是一個(gè)接口
type error interface {
Error() string //只要實(shí)現(xiàn)了這個(gè)方法,就算error
}
go中把‘異?!?dāng)中一個(gè)值來(lái)處理,所以并沒(méi)有try catch的語(yǔ)法,而是通過(guò)判斷error是否為nill來(lái)進(jìn)行異常處理。
// 內(nèi)部error的處理
func ErrorTest(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("b can not be zero")
}
return a / b, nil
}
// 調(diào)用
v,error:=ErrorTest(1,0)
if error !=nill{
// 處理有錯(cuò)誤的情況
return
}
//...正常的處理
Panic和recove
panic用于手動(dòng)拋出致命異常,直接宕機(jī),程序線(xiàn)程停止。
recover 獲取宕機(jī)時(shí)的信息,配合defer關(guān)鍵字,讓程序在宕機(jī)后能繼續(xù)從斷點(diǎn)處開(kāi)始運(yùn)行。