Go随笔——函数的用法

wujunqi1996 · · 459 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

定义

函数包含函数名,行参列表,函数体和返回值列表,使用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")

}



有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:wujunqi1996

查看原文:Go随笔——函数的用法

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

459 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传