您的位置:首页 > 编程语言 > Go语言

谈一谈Go的函数function的使用方法

2017-12-13 14:18 274 查看
函数是基本的代码块,用于执行一个任务。Go 语言最少有个 main() 函数。你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。函数声明告诉了编译器函数的名称,返回类型,和参数。Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数字,则返回数组中包含的函数个数。
自定义函数

package main

import (
"fmt"
)

//值拷贝(值传递)、地址拷贝(地址传递)
func main() {
a := 1
myfun(a)
fmt.Println("main里输出,这是值传递", a)
}

func myfun(a int) {
a = 2//值传递不会改变原来的值
fmt.Println("myfun里输出,这是值传递", a)
}


输出:

  myfun里输出,这是值传递 2
  main里输出,这是值传递 1

package main

import (
"fmt"
)

//值拷贝(值传递)、地址拷贝(地址传递)
func main() {
a := 1
myfun(&a)
fmt.Println("main里输出,这是地址传递", a)
}

func myfun(a *int) {
*a = 2 //地址传递会改变原来的值
fmt.Println("myfun里输出,这是地址传递", *a)
}


输出:

  myfun里输出,这是地址传递 2
  main里输出,这是地址传递 2

函数赋值
package main

import (
"fmt"
)

func main() {
a := A //a变成了函数类型
a()
}

func A() {
fmt.Println("函数类型")
}


输出:
函数类型

匿名函数
package main

import (
"fmt"
)

func main() {
a := func() {
fmt.Println("匿名函数")
}
a()
}


输出:

匿名函数

闭包

package main

import (
"fmt"
)

func main() {
f := closure(10)
fmt.Println(f(1))
fmt.Println(f(2))
}

//闭包可以使局部变量递增
//因为打印出的3次x的地址都是一样的,所以他们指向同一个x地址,不是值得拷贝,而是指向x的原始地址
func closure(x int) func(y int) int {
fmt.Printf("%p\n", &x)
return func(y int) int {
fmt.Printf("%p\n", &x)
return x + y
}
}


输出:

  0xc042048080
  0xc042048080
  11
  0xc042048080
  12

不定长传参

package main

import (
"fmt"
)

func main() {
A("GO", 1, 2, 3, 4, 5, 6, 7, 8, 9)
}

//不定长变参,注意的是当有多种类型的参数时,不定长参数应该写在最后面
func A(s string, a ...int) {
//其实a就是一个slice
fmt.Println(s, a)
}


输出:
GO [1 2 3 4 5 6 7 8 9]

defer的使用(GO里的“析构函数“)

package main

import (
"fmt"
)

func main() {
fmt.Println("a")
//注意的是:函数体执行结束后按照调用顺序的相反顺序逐个执行,所以先输出c,再输出b
defer fmt.Println("b")
defer fmt.Println("c")
}


输出:

  a
  c
  b

没有匿名函数,就没有使用闭包

package main

import (
"fmt"
)

func main() {
for i := 0; i < 5; i++ {
defer fmt.Println(i)//i作为参数传入,则就是当前循环时i值的拷贝,由于defer是倒序执行的,即从4开始,一直到0
}
}


输出:

  4
  3
  2
  1
  0

有匿名函数,即使用闭包

import (
"fmt"
)

func main() {
for i := 0; i < 5; i++ {
//如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已经获得了拷贝,否则则是引用某个变量的地址
//为什么5次输出都是5?
//因为i一直都是作为引用,作为局部变量i,而上个例子则是作为参数传进去,所以运行到defer时就对i的值进行了拷贝,所以会输出4,3,2,1,0,而现在这个i是作为地址的引用,引用了局部变量,所以退出for循环体的时候就变成了5,而在这个匿名函数return的时候,就开始执行defer语句,那这时defer就是引用i等于3的情况,因为for循环了5次,类似于for里有5个defer表达式,那么就会打印出5个5,这个就是defer与匿名函数、以及在闭包里使用注意的地方。
defer func() {
fmt.Println(i)
}()
}
}


输出:

  5
  5
  5
  5
  5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: