当前位置: 首页 > news >正文

南山区住房和建设局网站官网中国疾控卫生应急服装

南山区住房和建设局网站官网,中国疾控卫生应急服装,西安免费自助建站模板,wordpress商业主体Go语言中的函数go语言中函数特性go语言有三种函数:普通函数、匿名函数(没有名称的函数)方法(定义在struct上的函数)。receivergo语言中不运算函数重载(overload),也就是说不允许函数…

Go语言中的函数

go语言中函数特性

  1. go语言有三种函数:普通函数、匿名函数(没有名称的函数)方法(定义在struct上的函数)。receiver

  1. go语言中不运算函数重载(overload),也就是说不允许函数同名

  1. go语言中的函数不能嵌套,但是可以嵌套匿名函数

  1. 函数是一个值,可以将函数赋值给变量,使得这个变量也成为函数

  1. 函数可以作为参数传递给另一个函数

  1. 函数的返回值可以是另一个函数

  1. 函数调用的时候,如果有参数传递给函数,则先拷贝参数的副本,再将副本传递给函数

  1. 函数参数可以没有名称

go语言中函数的定义和调用

函数在使用之前必须先定义,可以调用函数来完成某个任务,函数可以重复调用,从而达到代码的复用

func function_name([parameter_list])[return_types]{函数体
}

package mainimport "fmt"func sum(a int, b int) (res int) {res = a + breturn res
}
func main() {res := sum(1, 2)fmt.Printf("res: %v\n", res)
}
package mainimport "fmt"func compare(a int, b int) (max int) {if a > b {max = a} else {max = b}return max
}
func main() {res := compare(1, 2)fmt.Printf("res: %v\n", res)
}

go语言中的return

  1. 没有返回值

  1. 有一个返回值 (例如上面的求和以及比较两个数的大小的函数)

  1. 存在多个返回值,且在return中指定返回的内容

  1. 多个返回值,返回值名称没有被使用

  1. return覆盖命名返回值,返回值名称没有被使用

package mainimport "fmt"func test() {fmt.Print("testing...")
}
func main() {test()
}
package mainimport "fmt"func test() (string, int) {name := "Y4y17"age := 24return name, age
}
func main() {name, age := test()fmt.Printf("name: %v\n", name)fmt.Printf("age: %v\n", age)
}
package mainimport "fmt"func test() (name string, age int) {name = "Y4y17"age = 24return		//相当于return name,age
}
func main() {name, age := test()fmt.Printf("name: %v\n", name)fmt.Printf("age: %v\n", age)
}
package mainimport "fmt"func test() (name string, age int) {n := "Y4y17"	//重新定义了n和a,那么返回的时候只能返回n和a,而不是name和agea := 24			//这种情况一般不这样写,一般就是直接去掉返回值中的name和age,只保留类型return n, a
}
func main() {name, age := test()fmt.Printf("name: %v\n", name)fmt.Printf("age: %v\n", age)
}
  1. Go中经常会使用其中一个返回值作为函数是否执行成功、是否有错误信息的判断条件;例如return value,exists、return value,ok、return value,err等

  1. 当函数的返回值过多的时候,例如有4个以上的返回值,应该将这些返回值收集到容器中,然后以返回容器的方式去返回。例如,同类型的返回值可以放进slice中,不同类型的返回值可以放进map中。

  1. 当函数有多个返回值的时候,如果其中某个或者是某几个返回值不想用,可以通过下划线_来丢弃这些返回值。

函数的参数

package mainimport "fmt"func test(a int) {a = 200	//test函数中修改变量a的值为200
}
func main() {a := 5	//定义变量a的值为5test(a)fmt.Printf("a: %v\n", a)//输出a的值,依然还是5
}

数组、切片、指针都是传地址,也就是传址的方式;

package mainimport "fmt"func test(s []int) {s[2] = 17
}
func main() {s := []int{1, 2, 3, 4}test(s)fmt.Printf("s: %v\n", s)//输出的结果为s: [1 2 17 4]
}

变长参数

package mainimport "fmt"
//其实就像是传递了一个数组或者是切片
func test(args ...int) {for _, v := range args {fmt.Printf("v: %v\n", v)}
}
func main() {test(1, 2, 3, 4, 5, 6, 7)
}
package mainimport "fmt"func test(name string, b bool, args ...int) {fmt.Printf("name: %v\n", name)fmt.Printf("b: %v\n", b)for _, v := range args {fmt.Printf("v: %v\n", v)}
}
func main() {test("Y4y17", true, 1, 2, 3, 4, 5, 6, 7)
}

函数中的type关键字

相当于在c语言中的typedef关键字,说白了就是对现有的数据类型起了一个别名

package mainimport "fmt"func add(a int, b int) int {return a + b
}
func comp(a int, b int) int {if a > b {return a} else {return b}
}
func main() {type f func(a int, b int) intff := addr := ff(1, 2)fmt.Printf("r: %v\n", r)ff = compr = ff(1, 2)fmt.Printf("r: %v\n", r)
}

Go高阶函数

  1. 函数作为参数

package mainimport "fmt"func test(name string, f func(string)) {	f(name)
}
func sayHello(name string) {fmt.Printf("Hello: %v\n", name)
}
func main() {test("Y4y17", sayHello)
}

//test函数接受两个参数,分别是string类型的name和func(函数类型)的f(函数名)

sayHello函数接受一个参数,即string类型的name,主函数中调用test函数,传递参数Y4y17,和sayHello函数名;那么test函数中便会执行sayHello("Y4y17")

  1. 函数作为返回值

package mainimport "fmt"func add(a int, b int) int {return a + b
}
func sub(a int, b int) int {return a - b
}
func test(operate string) func(int, int) int {//test函数接受一个string类型的参数operate,test函数返回值是一个函数,该函数有两个int类型的参数并且返回值也是int类型switch operate {case "+"://当operate是+的时候,返回add方法return addcase "-"://当operate是-的时候,返回sub方法return subdefault:return nil}
}func main() {f := test("-")res := f(1, 2)fmt.Printf("res: %v\n", res)
}

匿名函数

前面提到了在函数中是不允许嵌套函数的,但是我们可以使用匿名函数,来实现一些简单的功能:

package mainimport "fmt"func main() {//匿名函数和普通函数的区别其实就是没有了函数的名字,当在一个函数中不写函数名的时候就是匿名函数max := func(a int, b int) int {if a > b {return a} else {return b}}(1, 2)	//直接在最后面加上()以及实参的时候,就是自己调用自己//r := max(3, 8)	//fmt.Printf("r: %v\n", r)fmt.Printf("max: %v\n", max)
}

Golang闭包

闭包可以理解成定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁,或者是说函数和其引用环境的组合体

闭包指的是一个函数和与其相关的应用环境组合而成的实体。简单来说,闭包=函数+引用环境。看下面的例子:

package mainimport "fmt"//定义一个函数名为test,该函数返回值是一个函数,这个函数有一个int类型的参数 并且他返回值是一个int类型的数
func test() func(int) int {var x intreturn func(i int) int {x += ireturn x}
}
func main() {f := test()//f赋值为test的返回值,就是返回的函数,初始x为0fmt.Printf("f(10): %v\n", f(10))	//计算0+10=>10 这里x就变成了10 而不是0fmt.Printf("f(20): %v\n", f(20))	//计算10+20=>30 这里x就变成了30 而不是10fmt.Printf("f(30): %v\n", f(30))	//计算30+30=>60 这里x就变成了60 而不是30
}

变量f是一个函数并且他引用了其外部作用域中的x变量,此时f就是一个闭包。在f的生命周期内,变量x也一直有效;

package mainimport ("fmt""strings"
)func makeSuffixFunc(suffic string) func(string) string {return func(name string) string {//这里的strings.HasSuff(name.suffic)表示判断name是否以suffic结尾//如果是返回true,否则false	需要导包stringsif !strings.HasSuffix(name, suffic) {return name + suffic} else {return name}}
}
func main() {f := makeSuffixFunc("World")str := f("Hello")fmt.Printf("str: %v\n", str)
}
package mainimport "fmt"func cal(base int) (func(int) int, func(int) int) {add := func(a int) int {base += areturn base}sub := func(a int) int {base -= areturn base}return add, sub
}
func main() {add, sub := cal(10)res := add(10)fmt.Printf("res: %v\n", res)res = sub(5)fmt.Printf("res: %v\n", res)
}

定义了cal函数,cal函数存在一个形参base,cal函数返回值存在两个,并且这两个都是函数,之后在cal函数中定义两个匿名的函数分别赋值给add 和 sub,最终cal函数返回这两个匿名函数,之后在main函数中,令add sub为cal(10) ,其中base就是10 之后执行res=add(10),而这个10是匿名函数的形参a=10,执行base+=a故base=20

base的值会存储下来,之后res = sub(5),此时sub函数中的形参a就是5,再次执行base-=a,故得到base=15

Go语言中的递归函数

函数内部调用函数自身的函数称之为递归函数

使用递归函数最重要的三点:

  1. 递归就是自己调用自己

  1. 必须先定义函数的退出条件,没有退出条件,递归将成为死循环

  1. go语言递归函数很可能会产生一大堆的goroutine,也很可能会出现占空间内存溢出的问题

package mainimport "fmt"//数的阶乘
func fc(n int) int {if n <= 1 {return 1} else {res := n * fc(n-1)return res}
}
func main() {res := fc(5)fmt.Printf("res: %v\n", res)
}
package mainimport "fmt"
//f(n)=f(n-1)+f(n-2) f(2)==f(1)==1
func fb(n int) int {if n <= 2 {return 1} else {res := fb(n-1) + fb(n-2)return res}
}
func main() {fmt.Printf("fb(3): %v\n", fb(3))
}

Go语言中的defer语句

go语言中的defer语句会将其后面跟随的语句进行延时处理,在defer归属的函数即将返回时,姜堰市处理的语句按defer定义的逆序进行执行;也就是说先被defer的语句最后被执行,最后被defer的语句,最先被执行

package mainimport "fmt"func main() {fmt.Printf("start...\n")defer fmt.Printf("stop1...\n")defer fmt.Printf("stop2...\n")defer fmt.Printf("stop3...\n")fmt.Printf("END...\n")
}

输出结果如下:

Go语言中的init函数

golang有一个特殊的函数init函数,先于main函数的执行,主要实现包级别的一些初始化操作

init函数额主要特点

  1. init函数先于main函数自动执行,不能被其他函数调用

  1. init函数没有输入参数、返回值

  1. 每个包可以有多个init函数

  1. 包的每个源文件也可以有多个init函数,这点比较特殊

  1. 同一个包的init执行顺序,golang没有明确的定义;

  1. 不同包的init函数按照包导入的依赖关系决定执行顺序

初始化顺序:变量初始化>init()>main()

package mainimport "fmt"var i int = initVar()func initVar() int {fmt.Printf("initvar...\n")return 100
}
func init() {fmt.Printf("init2...\n")
}
func init() {fmt.Printf("init...\n")
}
func main() {fmt.Printf("start...\n")
}

输出结果为:

同时存在多个init()的时候,遵循自上而下的执行顺序

http://www.dt0577.cn/news/16539.html

相关文章:

  • 怎样在网站上做免费的网业站长之家seo综合
  • 网站开发好做吗营销方案包括哪些内容
  • 河南郑州网站建设国内网络销售平台有哪些
  • 河南省建设厅举报网站网店代运营公司哪家好
  • 公司建网站怎么建新闻今日要闻
  • 网站建设找祥赢网店培训
  • 灰色网站怎么做佛山百度提升优化
  • 重庆哪家公司做网站好北京百度推广优化
  • 1m带宽做网站百度推广账号注册
  • hybrid app网站app计算机培训机构排名前十
  • 有哪些用960gs做的网站项目优化seo
  • 微商城网站建设平台合同范本新闻头条今日要闻国内新闻最新
  • 新建的网站百度搜索不到西点培训前十名学校
  • wordpress博客建站杭州seo
  • 仿魔酷阁网站源码seo需要付费吗
  • 湘潭做网站百度收录提交申请
  • 济南cms建站营销型网站建设企业
  • 科技公司名字大全谷歌seo 外贸建站
  • 网站用什么字体做正文seo点击排名软件哪里好
  • 手机网站客服系统设计网站如何添加友情链接
  • 陕西网站开发联系电话手机优化软件哪个好用
  • 做网页的软件下载seo推广
  • 在线天堂おっさんとわたし商品seo优化是什么意思
  • html网页制作小刘在线课程seo网站推广免费
  • 设计师必去十大网站sem培训班培训多少钱
  • 简述网站制作方案和主要内容搜索引擎排名查询工具
  • 网站开发电商品牌推广与传播
  • 网站的想法今日国内新闻头条大事
  • 拖拽式网站建设哪家专业独立站seo建站系统
  • 搭建网站用什么软件云搜索网页版入口