1. 程式人生 > >go基本語法

go基本語法

go基本語法

變數

基本型別

  1. bool預設false
  2. int以及int8int32
  3. string用雙引號或反引號括起來。反引號括起來的為raw字串,即自動轉義換行等字元
  4. error錯誤型別

定義變數

  1. var開頭,後跟變數名,再跟型別:var a int var a,b,c int var a int = b
    var a,b,c int = x,y,z
  2. 如果定義以後賦值可以體現型別,則可以不寫型別:var a=1 var a,b = x,y
  3. 此時也可以省略vara:=1 a,b := x,y(次形式僅限用於函式體)
  4. 特殊變數_。賦值給_的值會被丟棄。如_,a := 1,2會把2賦給a,同時1被丟棄
  5. 宣告未使用的變數會編譯報錯
  6. iota作用域內每使用一次會自增,同一行使用時值相同

陣列

  1. 定義:arr:=[]int{},arr:=[10]int{1,2},arr:=[...]int{1,2,3}
  2. 獲取長度:len(arr)
  3. 多維陣列arr:=[...][...]int{[...]int{1},[1]int{2}}

slice

陣列切片;引用型別,同一陣列的slice指向同一陣列;
1. 定義:var s []int(不指定長度)
1. arr:=[...]int{1,2,3}表示陣列s:=arr[0:2]表示從在陣列arr從0到2的切片
1. s:=arr[:2]從0到2
1. s:=arr[1:]從1到len(arr)

map

無序;引用型別;
1. 定義:var m map[string]intm:=make(map[string]int)
1. 初始化:m:=map[String]int{"a":1,"b":2}
1. 賦值:m["key"]=1

struct

struct的組合即為面向物件中的類
1. struct組合
1. 匿名欄位
1. 組合struct同名欄位:優先訪問外層

自定義型別

type Pair map[string]int自定義一個型別

常量

const a = 1

語句

  1. 選擇if
  2. 迴圈for

函式(面向過程的函式)

定義函式

第一行 以func開頭,後跟函式名,然後小括號內參數列表,以{結尾,然後是函式體,最後以}結束。

函式返回值

如果需要有返回值,則在引數列表後跟小括號,括號內寫返回值型別

func get()(a int,b int){
    a=1
    b=2
    return
    // 同return 1,2
}

變長引數

func get(arg ...int){
    for n := range arg{
        // process n
    }
}

傳值與傳指標

  1. 對於基本型別,同C
  2. 指標在定義時需要些*,而使用時會自動取址和指向(不用寫&*

函式作為型別與變數

// 定義一種函式型別
type testInt func(int) bool

// 定義該項型別方法
func bigThanZero(v int) bool {
    return v > 0
}

// 定義該項型別方法
func smallThanZero(v int) bool {
    return v < 0
}

// 方法作為引數
func process(v int, f testInt) bool {
    a := 0
    return f(a)
}

func main() {
    a := 0
    // 方法作為變數
    process(a, bigThanZero)
}

方法(面向物件的方法)

帶接收者的函式

// r為變數名,Receiver為接收者型別
func (r Reciever) f(){

}

方法的繼承

  1. 不像java或c#的方法是定義在類中的,go的方法是定義在struct之外
  2. struct組合時可以繼承其對應的方法

重寫繼承的方法

宣告方法時,指定新的接受者即可

interface

// 定義介面I
type I interface{
    fun1()
    fun2(arg string)
}

介面作為引數

同Java

介面定義變數

同Java

comma-ok

類似java中instanceof

func main() {
    m := map[string]Thing{"key": O{"a"}}
    // m["key"].(Thing)類似java中m.get("key") instanceof Thing
    if value, ok := m["key"].(Thing); ok {
        value.create()
    }

}

type Thing interface {
    create()
}

type O struct {
    name string
}

func (o O) create() {
    o.name = "1"
}

也支援switch-case

func main() {
    m := map[string]Thing{"key": O{"a"}}
    // m["key"].(Thing)類似java中m.get("key") instanceof Thing
    if value, ok := m["key"].(Thing); ok {
        value.create()
    }
    switch m["key"].(type) {
    case Thing:
        // process
    case O:
        //process
    }

}

type Thing interface {
    create()
}

type O struct {
    name string
}

func (o O) create() {
    o.name = "1"
}

介面繼承

類似struct的繼承,或者叫組合

type i interface{
    anotherInterfacce
}

程式碼分組

import "fmt"
import "os"

const i=100
const pi=3.14
const pre = "go"

var i int
var pi float
var pre string

可改寫為

import(
    "fmt"
    "os"
)

const(
    i=100
    pi=3.14
    pre="go"
)
var(
    i int
    pi float
    pre string
)

規則

  1. 大寫字母開頭變數可匯出,小寫字母開頭變數不可匯出
  2. 大寫字母開頭函式為公有,小寫字母開頭變數為私有

defer

  1. 作用類似java中的try-catch
  2. 寫法類似java中的assert
  3. 執行時機為函式返回前,後寫的先執行
func f(){
    file.Open("file");
    defer file.Close();
    // process
}

併發

方法前加go關鍵字,即可非同步呼叫

go run()

主動讓出CPU

runtime.Gosched()

通訊channel

  1. 定義處理int的channelc:=make(chan int)
  2. 傳送資料到channelc <- 2
  3. 從channel接收資料i := <- c
  4. 定義處理int的channel,並指定緩衝區大小為2個intcc := make(chan int, 2)
  5. 手動關閉close(c)
  6. 判斷是否開啟v,ok := <-c

select

select之於channel,類似switch之於int

runtime

併發控制

Tips

if邏輯快內定義變數

//在if邏輯塊內,允許宣告一個變數,作用域只在塊內有效
if x:= get(); x>10{

}

make、new

make返回值,new返回指標

標籤

可用於gotobreakcontinue

for-range

m:=map[string]int{"a":1}
for k,v:=range m{
    // process k,v
}
for  _,v:=range m{
    // process v
}

switch自動break

不用手寫break自動結束case
如需強制執行下一個case,則需在當前case最後加上fallthrogh

合併case

switch i{
    case 1:
    case 2,3:
}