package main
import "fmt"
func add(x, y int) (ret int) {
//x的类型省略,x和相邻的y同类型,返回值指定为ret int,如果返回值仅int,则可返回任意的int数据
ret = x + y //ret直接使用,无须再定义
return //可以省略ret,不能省略return
}
func main() {
ret := add(10, 20)
fmt.Println(ret)
}
package main
import "fmt"
//有一个整数参数x和一个可变参数nums,编写函数实现x是否在nums中出现
func hasX(x int, nums ...int) bool {
for _, v := range nums {
if x == v {
return true
}
}
return false
}
func main() {
has := hasX(10, 12, 34, 65, 78)
if has {
fmt.Println("x出现在nums切片中")
} else {
fmt.Println("x没有出现在nums切片中")
}
}
10会传参给x,12, 34, 65, 78会以切片形式传参给nums,在hasX函数体内可以将nums当作切片处理。
package main
import "fmt"
func addSub(x, y int) (int, int) {
add := x + y
sub := x - y
return add, sub
}
func main() {
ret1, ret2 := addSub(20, 10)
fmt.Println(ret1, ret2)
}
addSub函数分别实现对传入参数相加和相减操作,并且返回两个结果,使用两个变量接受返回值。当然也可以对多个返回值指定名称,也可以如同省略参数类型一样省略返回值类型。
package main
import "fmt"
func addSub(x, y int) (add, sub int) {
add = x + y
sub = x - y
return
}
func main() {
ret1, ret2 := addSub(20, 10)
fmt.Println(ret1, ret2)
}
我们可以使用type关键字来定义一个函数类型,具体格式如下:
type calculation func(int, int) int
上面语句定义了一个calculation类型,它是一种函数类型,这种函数接收两个int类型的参数并且返回一个int类型的返回值。
简单来说,凡是满足这个条件的函数都是calculation类型的函数,例如下面的add和sub是calculation类型。
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
add和sub都能赋值给calculation类型的变量。
var c calculation
c = add
被赋值的c变量,类型是main.calculation类型,c()等同于add()
package main
import "fmt"
type calculation func(int, int) int
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
func main() {
var fun1, fun2 calculation
fun1, fun2 = add, sub
ret1 := fun1(20, 10)
ret2 := fun2(20, 10)
fmt.Printf("fun1:%T\tfun2:%T\n", fun1, fun2)
fmt.Println(ret1, ret2)
}
package main
import "fmt"
func add(x, y int) int {
return x + y
}
func sum(x, y int, op func(int, int) int) (ret int) {
//sum函数共有x,y,op三个参数,op的类型是op func(int, int) int,sum函数的返回值是ret int
ret = op(x, y)
return
}
func main() {
res := sum(10, 20, add)
fmt.Println(res)
}
当然函数也可以作为函数的返回值,如下匿名函数部分。
go语言也可以将函数看做是对象,先看看匿名函数作为函数返回值
package main
import "fmt"
func bag() func() {
return func() {
fmt.Println("hello,world")
}
}
func main() {
fun := bag()
fun()
}
如上,bag函数的返回值是一个匿名函数,定义fun变量接受这个匿名函数之后就可以调用它。
package main
import "fmt"
func bag() {
func() {
fmt.Println("hello,world")
}()
}
func main() {
bag()
}
如上,并不需要bag函数返回匿名函数,bag函数内需要立即调用,可直接在定义匿名函数体后加()
进行立即执行。
当然,也可以写成如下形式
package main
import "fmt"
func bag() {
fun:=func() {
fmt.Println("hello,world")
}
fun()
}
func main() {
bag()
}
闭包=函数+引用函数外变量
func adder() func(int) int {
var x int
return func(y int) int {
x += y
return x
}
}
上述adder中的匿名函数就是闭包,该匿名函数使用了其外部变量x。
package main
import "fmt"
func closebag(base int) (func(int) int, func(int) int) {
add := func(x int) int {
base += x
return base
}
sub := func(y int) int {
base -= y
return base
}
return add, sub
}
func main() {
fun1, fun2 := closebag(200)
a := fun2(10)
b := fun1(20)
fmt.Println(a, b)
}
上述closebag函数中的两个匿名函数分别使用了add、sub两个变量来接受,并且返回了这两个函数变量,在这两个匿名函数中都使用了其函数外部变量base。因此这两个匿名函数都属于闭包。
package main
import (
"fmt"
"strings"
)
//检查字符串name是否值由suff字符结尾,如果不是返回name+suff
func checkSuff(suff string) (func(string)string) {
//checkSuff的返回值是一个有string类型参数和string类型返回值的匿名函数
return func(name string)string{
if !strings.HasSuffix(name,suff){
return name+suff
}
return name
}
}
func main() {
fun:=checkSuff(".doc")
str:=fun("word")
fmt.Println(str)
}