定义
函数包含函数名,行参列表,函数体和返回值列表,使用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")
}
有疑问加站长微信联系(非本文作者)