[筆記](méi)go語(yǔ)言基礎(chǔ)語(yǔ)法

image

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)行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容