[筆記]go語言基礎語法

image

0.基本語法結構

package main
import "fmt"
func main(){
  fmt.Println("Hello World")
}
- 聲明包
- 保留了大括號,但去掉了分號
- 和python有點像,但沒有強制鎖進
- 首字母大寫表示public,小寫表示private
- 和類c語言相似,都是從main函數開始執行

1、 變量

變量的聲明和初始化

go語言的變量聲明需要使用var一下,或者使用海象運算符

var x int =1 //長聲明
var y,z int =1024,2048 //多重聲明
p:=3 //海象運算符,短聲明
//如果沒有初始化,用默認值代替
const Pi=3.14 //常量,變量不可更改。聲明常量需要關鍵字const,禁止使用海象運算符

變量類型

go是強類型語言,對于數值類型的定義域和符號分的很清,除了所有語言都有的數字類型、字符串、數組外,還有一些go獨有的派生類型。

整數類型:int,int8,int32,int64,帶符號和不帶符號

浮點類型:Float32—單精度浮點值,Float64—雙精度浮點值

布爾類型:true,false

字符串類型:string

數組類型:array

指針類型:pointer
管道類型:chan

接口類型:interface

常量

const PI =3.1415926

2 、運算符

//算術運算符
x,y :=1,2
res:=x+y //加法
res:=x-y //減法
res:=x/y //除法,取整
res:=x%y //模,取余數
res+=x //賦值運算符,類似的*=,%=

//關系運算符
res:=x==y
res:=x!=y
res:=x>y
res:=x<y

//邏輯運算符
res:=x>0&&y>=0 //與門
res:=x>0||y>0 //或門
res:=!(x>y)//非門

3、 邏輯結構

判斷

//判斷語句
x:=1
if x>0{
  //... ...
}else{
  //... ...
}

循環


//for循環
for x:=1;x<10;x++{
  //...
}
// 省略初始化和迭代loop
x:=1
for x<10{
  //...
  x++
}

switch

//switch,注意go中沒有break語句,遇到第一個匹配的case就會跳出判斷,不會穿透
x:=1
switch x{
  case 1:
    //...
  case 2:
    //...
  case 3:
    //...
  default:
    //...
}

4、函數

函數結構

關鍵字、函數名、函數體、輸入參數,返回值

//基本結構,關鍵字、函數名、函數體、形參、返回值
func FunName(v int) string{
  return st
}
//多個參數的輸入和輸出
func FunName(v1 int ,v2 int)(int,string){
  return 2,"2"
}

可變參數

// 例子:求n個整數的和
func sum(x ...int) (s int) {
    //可變參數
    for _, v := range x {
        s += v
    }
    return
}
// 也可以直接把切片扔進去作為可變參數
arr=[3]int{1,2,3}
sum(arr...) //類似于解包的操作

閉包于匿名函數

閉包給了在內部函數捕獲外部函數參數的權利,匿名函數是閉包的實現方式之一,字面意思上的沒有名字,直接調用的函數。

// 函數的閉包
func test14(a int, b int) int {
    func() {
        fmt.Println(a, b)
    }()
    return a + b
}

5、指針

指針,即一個值的內存地址。在go中,&表示取地址,*表示取值。

指針聲明

var p1 *int
var p2 *string
// go中指針必須帶類型

6、結構體

定義數據使用,類似于其他面向對象語言中的class

type Contact struct{
  Age int
  Name string
}

結構體與指針

x:=&Contact{"ronron",12}
x.name="xiaojiji"

7、方法

結構體除了聲明了屬性外,還能定義方法,方法即帶接收器的函數。

type Contact struct{
  Name string
  Age int
}
// 方法,結構體接收器
func (c Constact) addAge1(){
  c.Age+=1 
}
// 方法,結構體指針接收器
func (c *Contact) addAge2(){
  c.Age+=1 
}


與普通函數相比,方法多了一個接收器,這個接收器可以是結構體,也可以是結構體指針。如果是結構體,那么傳遞的是結構體副本,修改不會影響原有的對象。如果是結構體指針,那么會影響原有的對象。

8、數組 Array

var a [3]int //定義一個長度為3的空數組
var a [3]int{1,2,3} //定義一個長度為3的數組并初始化
//數組的操作
// 索引
a[1]

數組一旦定義就無法修改大小,不方便使用,所以常用切片 slice代替

//切片定義方式一,直接從數組中切下來
a :=[5]int{1,2,3,4,5}
b:=a[1,3]

//切片定義方式二 ,使用make方法
c:=make([]int,5,10) //注意初始化長度為5,元素默認為0

//切片的遍歷,和python真的相似
    for i := 0; i < len(a); i++ {
        fmt.Println(a[i])
    }
    for _, v := range a {
        fmt.Println(v)
    }

切片

go語言中的數組一旦定義就不能再改變長度,不大好用。切片是數組的高一級別的抽象,可以理解為動態數組。


// 定義一個字符串的切片,初始長度為10,容量為20
s:=make([]string 10,20)

// 切片的索引,與python相似
s[1:3]

// 

9、字典Map

//直接定義和初始化map
m := map[string]int{
        "a": 1,
        "b": 2,
    }

// 使用make進行初始化
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、并發

并發是go語言提供的核心語法,相比其他語言多線程的方式,使用簡單,效率更高,管理便捷。

go例程中最核心的概念是goroutine和chan

goroutine

// 任務1
func A(){
  //do some thing a
}
//任務2
func B(){
  // do some thing b
}
//關鍵字go 直接使用例程,類似于其他語言中開辟一個新的線程
func main(){
  go A() //處理任務A
  go B() //處理任務B
}

channel

Channel用于多個goroutine 之間進行通信,<-符合指示數據的流動方向

// 創建一個channel
ch:=make(chan int)
// 向chan中發射數據
ch <- 1
// 從chan中接受一個數據
value := <-chan
// 不用變量接收也可以
<- chan

11 錯誤處理

go中沒有exception的概念,取而代之的是error,error在go中是一個接口

type error interface {
    Error() string //只要實現了這個方法,就算error
}

go中把‘異常’當中一個值來處理,所以并沒有try catch的語法,而是通過判斷error是否為nill來進行異常處理。


// 內部error的處理
func ErrorTest(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("b can not be zero")
    }
    return a / b, nil
}
// 調用
v,error:=ErrorTest(1,0)
if error !=nill{
  // 處理有錯誤的情況
  return
}
//...正常的處理

Panic和recove

panic用于手動拋出致命異常,直接宕機,程序線程停止。

recover 獲取宕機時的信息,配合defer關鍵字,讓程序在宕機后能繼續從斷點處開始運行。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容