golang基础之函数
1、为什么需要函数?
有些相同的代码可能出现多次,如果不进行封装,那么多次写入到程序中,会造成程序冗余,并且可读性降低
2、什么是函数
为完成某些特定功能的程序指令集合称为函数
3、函数分类
内建函数
自定义函数
4、函数的基本用法
基本语法
func 函数名(形参列表) (返回值列表) {
//执行语句
return 返回值列表
}
形参列表
表示函数的输入
执行语句
表示函数执行的某功能代码
返回值列表
函数可以有返回值也可以没有返回值,可以返回多个,也可以一个也不返回
使用注意
golang中的函数可以返回多个值,如果需要返回多个值,需要在自定义函数时,声明的返回值列表必须是多个,否则报错
案例演示
package main import ( “fmt” ) func main(){ key := 12 var a int = 9 if key >= 10 { k,b := test(a) //调用函数 fmt.Println(k,b) fmt.Printf("%T",k) } } func test(a int) (float32, int){ //声明函数 var t int = 3 b := float32(a + t) c := a + t return b,c } 运行结果: 12 12 float32
5、函数参数的传递方式
基本介绍
函数参数传递分为值传递和引用传递
分类
值传递
基本数据类型、数组和结构体等都是值类型,值类型采用的是值传递
引用传递
指针、slice切片、map、管道chan、接口等都是引用类型,引用类型采用的是引用传递
使用说明
其实不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是值传递是值的拷贝,引用传递的是地址的拷贝,一般来说,地址的拷贝效率比较高,因数据量小,而值拷贝拷贝的效率取决于数据的大小,数据越大,效率越低
6、变量作用域
基本介绍
函数内部声明或者定义的变量叫做局部变量,作用域仅限于函数内部
函数外部声明的或者定义的变量叫做全局变量,作用域在整个包都有效,全局变量如果在整个程序有效的前提是首字母必须大写
注意事项
如果变量被定义在一个代码块中,比如if或者for循环中,那么这个变量的作用域就在该代码块中
变量的赋值不能再全局作用域进行,否则会报错。全局作用域只能声明一些变量或者函数,不能进行赋值操作
案例演示
package main import ( "fmt" "strings" ) var name int name = 123 //错误的做法 name1 := 123 //错误的做法 func main(){ fmt.Print(name) } 案例演示 package main import “fmt” name := “zhangsan” func test(){ fmt.Print(name) //zhangsan } func test1(){ name := “wangwu” fmt.Print(name) //wangwu } func main(){ test() test1() } 运行结果 shangsan wangwu
7、函数使用的注意事项和细节讨论
(1) 函数的形参列表可以是多个,返回值列表也可以是多个,返回值列表,每个值用逗号隔开
(2) 形参列表和返回值列表的数据类型可以是值类型和引用类型
(3) 函数命名规范遵守变量命名规范,不能以数字开头,或者包含特殊字符,首字母大写,被其他包导入时,具有可访问性。如果是小写只能被本包使用
(4) 变量分为全局变量和局部变量,全局变量是声明在main函数中,局部变量可以声明在任何一个块结构中,比如if语句中,循环体中,自定义函数中等
(5) 基本数据类型的和数组在传递时默认都是值传递,即进行值的拷贝,在函数内部修改,不会影响原值
(6) 如果希望函数内部的变量修改函数外的变量,可以传入变量的地址&,函数内部已指针的方式操作变量,从效果看类似引用
案例演示
package main import “fmt” func test(n *int){ *n = *n + 1 fmt.Print(*n) } func main(){ num := 123 test(&num) fmt.Print(num) }
(7) go语言不支持传统的重载(也就是通过参数列表的不同来实现的重载),go语言是用另一种方式实现的重载,而不是通过参数列表的不同来实现重载
(8) 在Go中,函数也是一个数据类型,可以赋值给一个变量,则该变量就是函数类型的变量,通过该变量可以对函数调用
举例说明
package main import “fmt” func main(){ a := yanshi a() //通过把函数赋值给一个变量,变量加个括号来调用函数 fmt.Printf("%T %T",a,yanshi) } func yanshi(n int){ fmt.Print("案例演示") }
(9) 函数既然是一种数据类型,因此Go中,函数可以作为参数传递给另一个函数
举例说明
package main import “fmt” func main(){ a := myfunc(yanshi,12) fmt.Printf("%T %T \n",a,myfunc) fmt.Println(a) } func myfunc(funcvar func(int) int ,num int) { //函数作为参数时,必须把函数的参数列表和函数的返回值类型的列表补全 return funcvar(num) } func yanshi(n int){ fmt.Print("案例演示") }
(10) 函数作为参数传递时,必须把函数的声明和返回值的类型列表写全
(11) 为了简化数据类型的定义,Go支持自定义数据类型
基本语法
type 自定义数据类型名 数据类型
演示自定义数据类型
第一个演示: type myint int //相当于给int数据类型取了别名,但是这两个是独立,是不同的数据类型
第二个演示: type mysum func(int,int) int
关于自定义类型后与原类型的问题
使用注意
关于子自定义函数类型作用,能够简化函数类型作为形参的