函数是执行特定公开、可复用的代码块,包括函数、匿名函数、闭包。可作为变量、返回值、参数等。
func 函数名(参数)(返回值){
函数体
}
函数名:字母、数字、下划线组成,第一个字母不能是数字;同一个包内,函数名也不能重名;
返回值:可返回多个返回值,必须用()包裹,并用,分隔
函数定义与使用
func testOne(){
fmt.Println("Hello")
}
func testTwo(x int){
fmt.Println(x)
}
//多个同类型的参数,可省略前面的类型
func testThree(x, y int){
fmt.Println(x, y)
}
func testSum(x int, y int)int{
ret := x + y
return ret
}
func testSum2(x int, y int)(ret int){
ret = x + y
return
}
//可变参数,在函数体中是切片类型
//固定参数和可变参数一起出现时候,可变参数必须放到最后
//go语言中没有默认参数
func testSum3(a int, x ...int)int{
fmt.Printf("tyep:%T,content:%v\n", a, a)
fmt.Printf("tyep:%T,content:%v\n", x, x)
sum := 0
for _, value := range x {
sum += value
// sum = testSum2(sum, value)
}
return sum
}
//多个返回值情况,必须用括号包起来
//多个返回值,也支持参数简写
func calc(a, b int)(sum, sub int){
sum = a + b
sub = a - b
return
}
func main() {
testOne()
testTwo(2)
testThree(3, 3)
fmt.Println(testSum(1, 1))
fmt.Println(testSum2(2, 2))
sum1 := testSum3(1, 2, 3, 4, 5);
fmt.Println(sum1)
sum2 := testSum3(1, 2, 3, 4);
fmt.Println(sum2)
sum3 := testSum3(1);
fmt.Println(sum3)
sum, sub := calc(100, 200)
fmt.Println(sum, sub)
}
defer语句
将其后面跟随的语句进行延迟处理,在defer归属的函数即将返回时,讲延迟处理的语句按照defer定义的逆序进行执行(先被defer的语句最后执行,最后被defer语句,最先被执行)。
defer语句非常方便处理资源释放问题,比如资源清理、文件关闭、解锁及记录时间等。
//defer 延迟执行
func main() {
fmt.Println("start")
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
fmt.Println("end")
}
输出
start
end
3
2
1
作用域
函数内部可以访问全局变量,如果函数内部定义同名的局部变量,先取用局部变量;
外层不能访问函数的内部变量(局部变量);
外层访问不到内部for、if、switch语句块中的变量;
//定义全局变量
var num = 10
func test(){
fmt.Println("全局变量", num)
num := 20
fmt.Println("局部变量", num)
}
func main() {
test()
fmt.Println("全局变量", num)
}
输出
全局变量 10
局部变量 20
全局变量 10
函数作为变量
//定义全局变量
var num = 10
func test(){
fmt.Println("全局变量", num)
num := 20
fmt.Println("局部变量", num)
}
func main() {
//函数作为变量
abc := test
fmt.Printf("%T\n", abc)
//调用
abc()
}
输出
func()
全局变量 10
局部变量 20
函数作为参数
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
func calc(x, y int, op func(int, int) int) int{
return op(x, y)
}
func main() {
add := calc(100, 200, add)
fmt.Println(add)
sub := calc(100, 200, sub)
fmt.Println(sub)
}
匿名函数
没有函数名的函数
func(参数)(返回值){
函数体
}
func main() {
//匿名函数赋值给变量
test := func(){
fmt.Println("haha")
}
test()
//匿名函数直接使用
func(){
fmt.Println("hihi")
}()
}
闭包
闭包指的是一个函数和与其相关的引用环境组合而成的实体,即闭包=函数+引用环境。
//函数返回值是函数
func a() func() {
name := "lv"
return func(){
fmt.Println("haha", name)
}
}
func b(name string) func() {
return func(){
fmt.Println("haha", name)
}
}
func main() {
//闭包 = 函数 + 外层变量的引用
r := a()
r() //相当于执行了a函数内部的匿名函数
c := b("c")
c()
}
常用内置函数
内置函数
介绍
close
主要是用来关闭channel
len
求长度,例如string、array、slice、map、channel
new
主要分配值类型内存,例如 int、struct、string、array等,返回 的是指针
make
主要分配引用类型的内存,比如chan、map、slice
append
追加元素到array、slice中
panic和recover
用来错误处理
Go(1.12)没有异常处理,用panic和recover。
recover必须搭配defer使用
defer一定要在可能引发panic的语句之前定义
func a(){
fmt.Println("func a")
}
func b(){
defer func(){
err := recover()
if err != nil {
panic("func b error")
}
}()
panic("panic in b")
}
func c(){
fmt.Println("func c")
}
func main() {
a()
b() //程序崩溃
c()
}
有疑问加站长微信联系(非本文作者)