函数
- 1、无参数无返回函数
- 2、有参无返回
- 多个参数
- 3、不定参数类型
package main
import "fmt"
func MyFunc(a int ,b int) { //固定参数
fmt.Printf("%d")
}
//..int类型这样的类型 ...type不定参数类型
//注意:不定参数,一定(只能)放在形参中的最后一个参数
func MyFunc1(args ...int) {//传递的实参可以是0或者多个
//fmt.Println("len(args)",len(args)) //获取用户传递参数的个数
for i :=0;i<len(args) ;i++ {
fmt.Printf("args[%d] = %d\n",i,args[i])
}
fmt.Println("=================================")
//返回2个值,第一个是下标,第二个是下标所对应的数
for i,data :=range args{
fmt.Printf("args[%d] = %d\n",i,data)
}
}
//固定参数一定要传参,不定参数根据需求传递参数
func MyFunc2(a int,args...int) {
}
func main() {
//MyFunc(666,222)
MyFunc1()
fmt.Println("---------------------------------------")
MyFunc1(1)
fmt.Println("---------------------------------------")
MyFunc1(2,3,4)
}
- 4、不定参数传递
package main
import "fmt"
func myfunco1(tmp ...int) {
for _, data := range tmp{
fmt.Println("data =",data)
}
}
func myfunc2(tmp ...int) {
for _,data :=range tmp {
fmt.Println("data=",data)
}
}
func test(args ...int) {
//全部元素传递给myfunc01
//myfunco1(args...)
//只想把后2个参数传递给另外一个函数使用
myfunc2(args[2:]...) //从args[2]开始(包括本身),把后面的所有元素传递过去
myfunc2(args[:2]...) //0---2(不包括数字2下标),传递过去
}
func main() {
test(1,3,4,5)
}
- 5、多个返回值
package main
import "fmt"
//多个返回值
func myfunc11()(int,int,int) {
return 1,2,3
}
//go语言推荐写法
func myfunc12()(a,b,c int) {
a,b,c = 11,22,33
return
}
func main() {
//函数调用
a,b,c := myfunc12()
fmt.Printf("a=%d,b=%d,c=%d",a,b,c)
}
函数定义说明:
- funnc:函数由关键字func开始声明
- FuncName:函数名称,根据约定,函数名首字母小写即为:private,大写即为:public
- 参数列表:函数可以有0个活多个参数,参数格式为:变量名 类型,如果有多个参数通过逗号分隔,不支持默认参数
返回值类型: - 如果只有一个返回值且不声明名返回值变量,那么你可以省略,包括返回值的括号
- 如果没有返回值,那么就直接省略最后的返回信息
- 如果有返回值,那么必须在函数的内部添加return语句
-6、 有参有返回值
package main
import "fmt"
func MaxAndMin(a,b int) (max,min int) {
if a>b {
max =a
min =b
}else{
max =b
min =a
}
return //有返回值的函数,必须通过return
}
func main() {
//通过匿名变量丢弃某个返回值 max ,_ := MaxAndMin(10,20)
max ,min := MaxAndMin(10,20)
fmt.Printf("max = %d,,min = %d",max,min)
}
- 6、普通函数调用流程
package main
import "fmt"
func funnc(c int) {
fmt.Println("c =",c)
}
func funnb(b int) {
funnc(b-1)
fmt.Println("b= ",b)
}
func funna(a int) {
funnb(a-1)
fmt.Println("a = ",a)
}
func main() {
funna(3)
fmt.Println("main执行了")
}
-7、递归函数的调用流程
package main
import "fmt"
func test(a int) {
if a ==1 { //函数终止终止调用的条件非常重要
fmt.Println("a=",a)
return
}
//函数自身调用
test(a-1)
fmt.Println("a =",a)
}
func main() {
test(3)
fmt.Println("main")
}
- 8、数字累加
package main
import "fmt"
//实现1+2+3+4....100
func test01()(sum int) {
for i :=0;i<=100 ;i ++ {
sum += i
}
return
}
func test02(i int)int {
if i ==1{
return 1
}
return i +test02(i-1)
}
func test03(i int)int {
if i ==100{
return 100
}
return i +test03(i+1)
}
func main() {
//sum := test01()
//sum :=test02(100)
sum := test03(1)
fmt.Println("sum=",sum)
}
- 9、函数类型
package main
import "fmt"
func Sum(a,b int)int {
return a+b
}
func Minus(a,b int)int {
return a-b
}
//函数也是一种数据类型,通过type给一个函数类型起别名
//FuncType它是一个函数类型
type FuncType func(int ,int) int
func main() {
//传统调用方式
//result := Sum(1,1)
//result1 := Minus(1,1)
//声明一个函数类型的变量 变量名叫fTest
var fTest FuncType
//fTest =Sum //是变量就可以赋值
fTest =Minus
result := fTest(10,20) //相当于Minus(10,20)
fmt.Println("resultt=",result)
}
- 10、回调函数
- 优点:有利于拓展
package main
import "fmt"
func Add(a1,b1 int)int {
return a1+b1
}
func minum(a1,b1 int)int {
return a1-b1
}
//回调函数,函数有一个参数是函数类型 ,这个函数就是回调函数
//多态 多种形态
type FuncType1 func(int ,int)int
func Calc(a1,b1 int,fTest FuncType1)(result int){
fmt.Println("Calc")
result =fTest(a1,b1)
return
}
func main() {
//resultt := Calc(10,20,Add)
resultt := Calc(10,20,minum)
fmt.Println("result:",resultt)
}
- 11、匿名函数和闭包
package main
import "fmt"
func main() {
a := 10
str := "hello"
//定义匿名函数同时调用
func(){
fmt.Printf("a=%d, str=%s\n",a,str)
}() //后面的()代表调用此匿名函数
//定义匿名函数同时调用 (带参数的匿名函数)
func (a,b int){
fmt.Printf("a=%d,b=%d\n",a,b)
}(10,20)
//匿名函数,有参有返回值
x ,y :=func(c,d int)(max,min int){
if c >d {
max =c
min =d
}else {
max =d
min =c
}
return
}(10,20)
fmt.Printf("x =%d,y=%d\n",x,y)
}
- 12、闭包捕获外部变量的特点
package main
import "fmt"
func main() {
a := 10
str := "hello"
func(){
//闭包以引用方式捕获外部变量
a =333
str ="go"
fmt.Printf("内部: a =%d,str = %s\n",a,str)
}() //()表示直接调用
fmt.Printf("外部: a =%d,str = %s\n",a,str)
}
- 13、闭包的特点
- 闭包不关心这些捕获了的变量和常量是否已经超出了作用域,所以只有闭包还在使用它,这些变量就还会存在.
package main
import "fmt"
//函数的返回值是一个匿名函数,返回一个函数类型
func test001()func()int {
var x int
return func() int {
x++
return x*x
}
}
func main() {
//返回值为一个匿名函数,返回一个函数类型,通过f来调用返回的匿名函数
f :=test001()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
}
func test0() int {
var x int //没有初始化 值为0
x++
return x*x //函数调用完毕,x自动释放
}
func main1() {
fmt.Println(test0())
fmt.Println(test0())
fmt.Println(test0())
}
-14、defer的作用
package main
import "fmt"
func main() {
//defer延迟调用,main函数结束前调用
defer fmt.Println("main执行结束了")
fmt.Println("main执行开始了")
}
- 15、多个defer执行顺序
- 如果一个函数中有多个defer语句时,他们会以LIFO(先进先出)的顺序执行,函数或某个延时调用发生错误,这些调用依旧会被执行。
package main
import "fmt"
func tes(x int) {
result := 100/ x
fmt.Println("result=",result)
}
func main() {
defer fmt.Println("aaaaaa")
defer fmt.Println("bbbbbb")
//调用一个函数,导致内存出问题
defer tes(0)
defer fmt.Println("cccccc")
}
- 16 、全局变量
package main
import "fmt"
func tet() {
fmt.Println("tet a = ",a)
}
//全局变量在任何地方都可以使用
var a int
func main() {
a = 10
fmt.Println("a =",a)
tet()
}
- 17、不同作用域同名变量
package main
import "fmt"
//全局变量
var a1 byte
func main() {
//局部变量
var a1 int
//1不同作用域,允许定义同名变量
//2使用变量的原则 就近原则
fmt.Printf("%T\n",a1)
{
var a1 float32
fmt.Printf("%T\n",a1)
}
tess()
}
func tess() {
fmt.Printf("%T\n",a1)
}
- 18、多文件构建
1、将函数首字母大写
2、需要配置构建配置 (directory)选择文件夹
3、不同包的调用
目录结构