Go 函式詳解

2022-09-15 17:06:10 字數 4847 閱讀 5921

// 1. 可以沒有輸入引數,也可以沒有返回值(預設返回 0)

func a()

// 2. 多個相鄰的相同型別引數可以使用簡寫模式

func b(a, b int) int

// 3. 支援有名的返回值

func c(a, b int) (sum int)

// 4. 不支援預設值引數

// 5. 不支援函式過載

// 6. 不支援函式巢狀定義,但支援巢狀匿名函式

func d(a, b int) (sum int)

return e(a, b)

}// 7. 支援多值返回(一般將錯誤型別作為最後乙個返回值)

func f(a, b int) (int, int)

// 8. 函式實參到形參的傳遞永遠是**值拷貝**

func g(a *int)

// 1. 不定引數型別相同

// 2. 不定引數必須是函式的最後乙個引數

// 3. 不定引數在函式體內相當於切片

func sum(arr ...int) (sum int)

return

}// 4. 可以將切片傳遞給不定引數

array := [...]int // 不能將陣列傳遞給不定引數

slice := int

sum(slice...) // 切片名後要加 ...

// 5. 形參為不定引數的函式和形參為切片的函式型別不同

func suma(arr ...int) (sum int)

return

}func sumb(arr int) (sum int)

return

}fmt.printf("%t\n", suma) // func(...int) int

fmt.printf("%t", sumb) // func(int) int

函式型別又叫函式簽名:函式定義行去掉函式名、引數名和

func sub(x int, y int) (c int)

fmt.printf("%t", add) // func(int, int) int

fmt.printf("%t", sub) // func(int, int) int可以使用 type 定義函式型別。函式型別變數和函式名都可以看做指標變數,該指標指向函式**的開始位置

func add(a, b int) int 

func sub(a, b int) int

type op func(int, int) int // 定義乙個函式型別:輸入兩個 int,返回乙個 int

func do(f op, a, b int) int

fmt.println(do(add, 1, 2)) // 3

fmt.println(do(sub, 1, 2)) // -1

// 1. 直接賦值給函式變數

var sum = func(a, b int) int

func do(f func(int, int) int, a, b int) int

// 2. 作為返回值

func getadd() func(int, int) int

}func main()

}()sum(1, 2)

getadd()(1 , 2)

// 4. 作為實參

do(func(x, y int) int , 1, 2)

}

可註冊多個延遲呼叫函式,以先進後出的順序執行。常用於保證資源最終得到**釋放

func main() ()

defer func() ()

println("main")

}// main

// second

// first

defer 函式的實參在註冊時傳遞,後續變更無影響

func f() int (a)

a++return a

}print(f())

// defer i = 1

// 2

defer 若位於 return 後,則不會執行

func main() ()

}// main

若主動呼叫os.exit(int)退出程序,則不會執行 defer

func main() ()

println("main")

os.exit(1)

}// main

關閉資源例子

func copyfile(dst, src string) (w int64, err error) 

// defer 一般放在錯誤檢查語句後面。若位置不當可能造成 panic

defer srcfile.close()

dstfile, err := os.create(dst)

if err != nil

defer dstfile.close()

w, err = io.copy(dstfile, srcfile)

return

}

defer 使用注意事項:

// fa 返回的是乙個閉包:形參a + 匿名函式

func fa(a int) func(i int) int

}func main()

// 0xc0000200f0 1

// 2

// 0xc0000200f0 2

// 3

// 0xc0000200f8 1

// 2

// 0xc0000200f8 2

// 3

閉包引用全域性變數(不推薦)

var a = 0

// fa 返回的是乙個閉包:全域性變數a + 匿名函式

func fa() func(i int) int

}func main()

// 0x511020 0

// 1

// 0x511020 1

// 2

// 0x511020 2

// 3

// 0x511020 3

// 4

同乙個函式返回的多個閉包共享該函式的區域性變數

func fa(a int) (func(int) int, func(int) int) 

sub := func(i int) int

return add, sub

}func main()

// 0xc0000200f0 0

// 0xc0000200f8 0

// 0xc0000200f0 1

// 0xc0000200f0 -1

// 1 -1

// 0xc0000200f8 1

// 0xc0000200f8 -1

// 1 -1

異常:發生非期待的未知行為,又被稱為未捕獲的錯誤

go 提供兩種錯誤處理機制

go 是靜態強型別語言,程式的大部分錯誤是可以在編譯器檢測到的,但有些錯誤行為需要在執行期才能檢測出來,此種錯誤行為將導致程式異常退出。建議:

panic(i inte***ce{})  // 主動丟擲錯誤

recover() inte***ce{} // 捕獲丟擲的錯誤

// 以下場景捕獲失敗

defer recover()

defer fmt.println(recover())

defer func() ()

}()// 以下場景捕獲成功

defer func() ()

func except()

func test()

可以同時有多個 panic(只會出現在 defer 裡),但只有最後一次 panic 能**獲

func main() 

fmt.println(recover())

}()defer func() ()

defer func() ()

panic("main panic")

}// first defer panic

//

包中 init 函式引發的 panic 只能在 init 函式中捕獲(init 先於 main 執行)

函式不能捕獲內部新啟動的 goroutine 丟擲的 panic

func do() 

}()go da()

time.sleep(3 * time.second)

}func da()

go 內建錯誤介面型別 error。任何型別只要實現error() string方法,都可以傳遞 error 介面型別變數???

type error inte***ce
使用 error:

todo

go語言panic函式詳解

程式異常被叫做panic,直譯為執行時恐慌 當panic被丟擲異常後,如果我們沒有在程式中新增任何保護措施的話,程式就會列印出panic的詳細情況之後,終止執行 panic runtime error index out of range goroutine 1 running main.main ...

Go 延遲函式 defer 詳解

go 語言中延遲函式 defer 充當著 try.catch 的重任,使用起來也非常簡便,然而在實際應用中,很多 gopher 並沒有真正搞明白 defer return 返回值 panic 之間的執行順序,從而掉進坑中,今天我們就來揭開它的神秘面紗!先來執行下面兩段 package main im...

Go語言init函式詳解

go init函式詳解 init 函式會在每個包完成初始化後自動執行,並且執行優先順序比main函式高。init 函式通常被用來 包的初始化 為了使用匯入的包,首先必須將其初始化。初始化總是以單執行緒執行,並且按照包的依賴關係順序執行。hleufd這通過golang的執行時系統控制,如下圖所示 in...