函数
函数书写
这里只记录 有参有返回值函数 书写。
格式:
func 函数名(参数 参数类型, ...)(返回值 返回值类型, ...){
return
}
要点:
- 有返回值的函数,必须使用return结尾。
- 函数返回值可以有多个
- 支持不定项参数
- 函数首字母必须大写。否则不能跨包调用。
- 对于不需要的返回值,可使用 _ 接收
/*
有参有返回值函数的书写 demo
判断三个数中最大值与最小值,并返回
*/
package main
import "fmt"
func main(){
//使用_接收时,表示放弃接收
_, min2 := JudgeMaxAndMin(10, 20, 30)
fmt.Println("最小值为:",min2)
}
//格式: func 函数名(参数 参数类型, ...)(返回值 返回值类型, ...)
func JudgeMaxAndMin(a int,b int,c int) (max int,min int){
max = a
min = b
if(a < b){
max = b
min = a
}
if (c > max) {
max = c
}else if (c < min) {
min = c
}
//存在返回值时,必须使用return进行返回,以下两种写法皆可
return //方式1,只使用return
//return max,min //方式2:此处返回内容必须与函数头处声明相同
}
函数类型
Go语言中,函数也是一种数据类型。
可以通过type来定义,它的类型就是所有拥有相同的参数,相同的返回值的一种类型。
格式:type 函数类型名 func(参数类型, …)(返回值类型, …)
作用:用来实现函数的多态。
//自定义函数类型的实现demo。实现加减法计算的多态
package main
import "fmt"
/*
声明一个函数类型。可用来表示同种形式(同参同返回值)的函数。
作用:用来实现函数的多态。相当于Java中接口.
*/
type FuncType func(int, int) int
func main() {
//函数调用,可直接将函数作为参数传入。
result := Calc(10, 20, Add) //此时cala函数的具体计算取决于参数三中所传递的函数。
fmt.Println(result) //30
var f FuncType = Minus //将减法函数 赋值给 f。然后调用计算
fmt.Println("result = ", f(10, 2)) //result = 8
}
//第三个参数类型为函数类型:f FuncType
func Calc(a, b int, f FuncType) (result int) {
result = f(a, b) //通过调用f()实现任务
return
}
func Add(a, b int) int { //加法
return a + b
}
func Minus(a, b int) int { //减法
return a - b
}
匿名函数
匿名函数:指不需要定义函数名的函数实现方式
//匿名函数的创建与使用 demo
package main
import "fmt"
func main() {
i := 10
func(){ //创建匿名函数
i = 20
//内部:i = 20
fmt.Printf("内部:i = %d\n", i )
} () //()作用:此处直接调用该匿名函数
//外部:i = 20
fmt.Printf("外部:i = %d\n", i)
}
闭包
通俗理解:类是有行为的数据,闭包是有数据的行为。
构成:匿名函数 + 引用环境 = 闭包
//闭包demo
package main
import "fmt"
func main(){
p1:=test()
p2:=test()
fmt.Println(p1(),p1()) // 1 1
fmt.Println(p2(),p2()) // 2 2
}
func test() func() int{
t:=0
return func() int {
t++
fmt.Println("t的地址为",&t)
return t
}
}
运行结果:
结果分析:
- t := 0 这条语句在 p1:=test() p2:=test() 这两行执行的时候就执行完了。之后test()创建并返回一个独立的匿名函数。
- 每次执行p1()、p2()时,等于执行各自独立的匿名函数。
- 在创建匿名函数时,相当于独立创建了一份所有被引用变量的备份。变量备份会随匿名函数一直存在。并被使用。
defer
defer :⽤于延迟一个函数或者方法的执行。
使用场景:defer语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。
作用:通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。释放资源的defer应该直接跟在请求资源的语句后。
注意:
1.defer只能出现在函数或方法的内部。
2.多个defer时,以LIFO(后进先出)的顺序执行。
//defer与匿名函数一同使用
package main
import "fmt"
func main() {
a, b := 10, 20
defer func(x int) { // a以值传递方式传给x
fmt.Println("defer:", x, b) //10 120
}(a) //此结果说明,变量a在作为参数时,会先完成参数传递,不受defer影响
a += 10
b += 100
fmt.Printf("a = %d, b = %d\n", a, b) //20 120
}
随机数
math/rand
//随机数测试
import (
"fmt"
"time"
)
import "math/rand"
func main(){
fmt.Println("随机数测试")
Test1()
}
func Test1(){
//伪随机数:使用默认种子数(1)计算生成的随机数,每次随机数相同
fmt.Println("伪随机整数:",rand.Int()) //伪随机int数
fmt.Println("伪随机浮点数:",rand.Float64()) //伪随机float数
fmt.Println("0~n之间的伪随机整数:",rand.Intn(10)) //0~n之间的伪随机整数
fmt.Println("=========================")
//使用当前时间作为种子生成随机数
//time.Now() 当前时间
//time.Now().UnixNano() 自1970到当前时间 所经过的时间(纳秒单位)
rand.Seed(time.Now().UnixNano()) //以纳秒级当前时间 作为种子数
fmt.Println("随机整数:",rand.Int())
fmt.Println("随机浮点数:",rand.Float64()) //伪随机float数
fmt.Println("随机浮点数:",rand.Intn(30))
}