Go隨筆——函數的用法

定義

函數包含函數名,行參列表,函數體和返回值列表,使用func進行聲明,函數無參數或返回值時則形參列表和返回值列表省略

func name(parameters) returns {

}

形參列表需要描述參數名及參數類型,所有形參爲函數塊局部變量,返回值需要描述返回值類型


舉例

1.無參 無返回值

func sayHello() {

fmt.Println("hello world")

}


2.有參 無返回值

func say(name string, name2 string) {

fmt.Println("hello world:", name, name2)

}


3.有參 有返回值

func add (a int, b int) int {

return a + b

}


func main() {

say("abc", "vbn")

num = add(1, 2)

fmt.println(num) 

}


調用

函數通過函數名(實參列表)在調用過程中實參的每個數據會賦值給形參中的每個變量,因 此實參列表類型和數量需要函數定義的形參一一對應。

舉例

1.調用無參無返回值函數

sayHello()


2.調用有參無返回值類型

say("kk", "abc")


3.調用有參有返回值函數

n1, n2 := 1, 2

fmt.Printf("%d + %d = %d\n", n1, n2, add(n1+n2))


參數

1.參數類型合併

// 連續多個變量類型相同

// 保留最後一個元素類型,前面的類型都可以省略

// func add (a int, b int) int


func add (a, b int) int {

return a + b

}


func test(p1, p2 int, p3, p4 string) {

fmt.Println("%T, %T, %T, %T", p1, p2, p3, p4)

}


2.可變參數類型

// 1.可變參數,在一個方法中只能有一個

// 2.並且可變參數必須放在函數聲明參數列表最後


func test(args ...string) {

fmt.Println("%T, %#v", args, args)

}


//至少有n個參數

//add


func add(n1, n2 int, args ...int) int {

total := n1 + n2

for _, v := range args {

total += v

}

return total

}


func mult(n1, n2 int) int {

return n1 * n2

}



func main() {

test()

test("1")

test("1", "2")

fmt.Println(add(1,2,3,4))

}


返回值

1.多個返回值

func calc(n1, n2 int) (int, int) {

//a, b := 1, 2

r1 := mult(1, 2)

r2 := add(1, 2)

return r1, r2

}


函數類型

1.聲明&初始化&調用

//定義函數類型變量,並使用零值nil進行初始化

var callback func(n1, n2 int) (r1, r2, r3, r4 int)

fmt.Printf("%T, %v", callback, callback)


//賦值爲函數calc

callback = calc 

fmt.Println(callback(5, 2)) //調用calc函數


2.值類型與引用


import "fmt"


func main() {

// 在內存中申請內存新的空間,將a的值拷貝到b中

// 在修改a 不影響b

// 在修改a 影響b


//值類型 b = a,tmpAge修改不影響age

age := 30

tmpAge := age

tmpAge = 31

fmt.Println(age, tmpAge)


//引用類型 修改tmpUsers影響users

users make([]string, 10)

tmpUsers := users

tmpUsers[0] = "kk"

fmt.Printf("%#v, %#v\n", users, tmpUsers)

}


3. 值類型,函數內修改實參的值


func change(value int) {

value += 1

}


func changePointer(pointer *int) {

*pointer = *pointer + 1

}


func main() {

value := 1

change(value)

fmt.Println(value) // 1


changePointer(&value)

fmt.Println(value)  // 2

}


4.函數作爲形參

package main


import "fmt"


func calc(n1 int, n2 int, callback func(int, int) int) int {

// 不定義是什麼運算

// 通過函數參數傳遞我要進行運算

rt := callback(n1, n2)

if rt >= 0 && rt <= 100 {

return rt

}

return -1

}


func add(n1, n2 int) int {

return n1 + n2

}


func multi(n1, n2 int) int {

return n1 * n2

}


func main() {

fmt.Println(calc(1, 2, add))

fmt.Println(calc(10, 100, multi))

}


5.定義函數變量

package main


import "fmt"


func calc(n1 int, n2 int, callback func(int, int) int) int {

// 不定義是什麼運算

// 通過函數參數傳遞我要進行運算

rt := callback(n1, n2)

if rt >= 0 && rt <= 100 {

return rt

}

return -1

}


//第一種

func main() {

add := func(n1, n2 int) int {

return n1 + n2

}


multi := func(n1, n2 int) int {

return n1 * n2

}

fmt.Println(calc(1, 2, add))

fmt.Println(calc(10, 100, multi))

}


//第二種

func main() {

 

fmt.Println(calc(1, 2, func(n1, n2 int) int {

return n1 + n2

}))

fmt.Println(calc(10, 100, func(n1, n2 int) int {

return n1 * n2

}))

}


閉包


package main

import "fmt"


func addBase(base int) func(int) int {

return func(n int) int {

return base + n

}

}


func main() {

add1 := addBase(1)

fmt.Println(add1(5))


add10 := addBase(10)

fmt.Println(add10(3))

}


錯誤處理

1.error接口

Go語言通過error接口實現錯誤處理的標準模式,通過使用函數返回值列表中的最後一個值返回錯誤信息,將錯誤的處理交由程序員主動進行處理


error接口初始化方法

a)通過errors包的New方法創建

b)通過fmt.Errorf方法創建


//定義除法函數,若除數爲0則使用error返回錯誤信息

func div(n1, n2 int) int {

if n2 == 0 {

return -1, errors.New("除數爲0") 

}

return n1 / n2, nil

}


func main() {

if rt, err = div(1, 0); err == nil {

fmt.Println("nil")

}

else {

fmt.Println(err)

}


}



2.defer

defer關鍵字用戶聲明函數,不論函數是否發生錯誤都在函數最後執行(return之前),若使用defer聲明多個函數,則按照聲明的順序,先聲明後執行(先進後出),常用來做資源釋放,日記記錄工作


在函數退出時執行


func main() {

//defer 函數調用

defer func() {

fmt.Println("defer")

}

fmt.Println("main")


}


延遲執行,先輸出main,在輸出defer


func main() {

//defer 函數調用

defer func() {

fmt.Println("defer")

}()


defer func() {

fmt.Println("defer A")

}()


defer func() {

fmt.Println("defer B")

}()

fmt.Println("main")


}



輸出:

main

deferB

deferA

defer


defer是先進後出結構



3.panic與recover函數

go語言提供panic和recover函數用於處理運行時錯誤,當調用panic拋出錯誤,中斷原有的控制流程,常用於不可修復性錯誤。recover函數用於終止錯誤處理流程,僅在defer語句的函數中有效,用於截取錯誤處理流程,recover只能捕獲到最後一個錯誤。

a)panic


package main


import "fmt"


func main() {

defer func() {

fmt.Println("defer 01")

}()


panic("error go")

}



b)recover

//當未發生panic則recover函數得到的結果爲nil

func success() {

defer func() {

fmt.Println(recover())

}()

fmt.Println("success")

}


//當發生panic則recover函數得到的結果爲panic傳遞的參數

func failure() {

defer func() {

fmt.Println(recover())

}()

fmt.Println("failure")

panic("error")

}


//revover只能獲取最後一次的panic信息

func failure2() {

defer func() {

fmt.Println(recover())

}()

defer func() {

fmt.Println("failure 2")

}()


fmt.Println("failure")

panic("error")

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章