#go语言的函数问题#

go函数的特效

1:Go中有3种函数:普通函数、匿名函数(没有名称的函数)、方法(定义在struct上的函数)。
2:Go编译时不在乎函数的定义位置,但建议init()定义在最前面(如果有的话),main函数定义在init()之后,然后再根据函数名的字母顺序或者根据调用顺序放置各函数的位置。
3:函数的参数、返回值以及它们的类型,结合起来成为函数的签名(signature)。
4:函数调用的时候,如果有参数传递给函数,则先拷贝参数的副本,再将副本传递给函数。
5:由于引用类型(slice、map、interface、channel)自身就是指针,所以这些类型的值拷贝给函数参数,函数内部的参数仍然指向它们的底层数据结构。
6:函数参数可以没有名称,例如func myfunc(int,int)。
7:Go中的函数可以作为一种type类型,例如type myfunc func(int,int) int。
实际上,在Go中,函数本身就是一种类型,它的signature就是所谓的type,例如func(int,int) int。所以,当函数ab()赋值给一个变量ref_ab时ref_ab := ab,不能再将其它函数类型的函数cd()赋值给变量ref_ab。

8:Go中不允许函数重载(overload),也就是说不允许函数同名。
9:Go中的函数不能嵌套函数,但可以嵌套匿名函数。
10:Go实现了一级函数(first-class functions),Go中的函数是高阶函数(high-order functions)。这意味着:
函数是一个值,可以将函数赋值给变量,使得这个变量也成为函数
函数可以作为参数传递给另一个函数
函数的返回值可以是一个函数
这些特性使得函数变得无比的灵活,例如回调函数、闭包等等功能都依赖于这些特性。
11:Go中的函数不支持泛型(目前不支持),但如果需要泛型的情况,大多数时候都可以通过接口、type switch、reflection的方式来解决。但使用这些技术使得代码变得更复杂,性能更低。


参数和返回值

函数可以有0或多个参数,0或多个返回值,参数和返回值都需要指定数据类型,返回值通过return关键字来指定。

return可以有参数,也可以没有参数,这些返回值可以有名称,也可以没有名称。Go中的函数可以有多个返回值。

  • (1).当返回值有多个时,这些返回值必须使用括号包围,逗号分隔
  • (2).return关键字中指定了参数时,返回值可以不用名称。如果return省略参数,则返回值部分必须带名称
  • (3).当返回值有名称时,必须使用括号包围,逗号分隔,即使只有一个返回值
  • (4).但即使返回值命名了,return中也可以强制指定其它返回值的名称,也就是说return的优先级更高
  • (5).命名的返回值是预先声明好的,在函数内部可以直接使用,无需再次声明。命名返回值的名称不能和函数参数名称相同,否则报错提示变量重复定义
  • (6).return中可以有表达式,但不能出现赋值表达式,这和其它语言可能有所不同。例如return a+b是正确的,但return c=a+b是错误的

多返回值的应用场景:

1:Go中经常会使用其中一个返回值作为函数是否执行成功、是否有错误信息的判断条件。例如return value,exists、return value,ok、return value,err等。
2:返回多个值,有些没用要丢掉,解决方案 _   表示丢掉的值
  例如
func func_a() (a,b int){
    return
}

func main() {
    a,_ := func_a()
}


3:变长参数
   函数参数太多,希望把这些多余的赋值给一个变量,使用  ... 的形式 例如:
   func myfunc(a,b int,args...int) int {}

   相当于在函数内部弄的一个slice:   var args =  []int{}

   如果参数类型太多,可以把参数放在切片里面,然后传递给函数,调用当时 slice...  例如:
   func main() {
    s1 := []int{30,40,50,60,70}
    fmt.Println(min(10,20,s1...))
   }
 


func type
可以将func作为一种type,以后可以直接使用这个type来定义函数。也就是用type定义函数,例如:
package main

import "fmt"

type add func(a,b int) int

func main() {
    var a add = func(a,b int) int{
        return a+b
    }
    s := a(3,5)
    fmt.Println(s)
}


其他:

new适用于为值类(value type)的数据类型(如array,int等)和struct类型的对象分配内存并初始化,并返回它们的指针给变量。如v := new(int)
make适用于为内置的引用类的类型(如slice、map、channel等)分配内存并初始化底层数据结构,并返回它们的指针给变量,同时可能会做一些额外的操作

new 和 make 都是为了给变量初始化并且分配内存,不同点在于偏向的对象不一样,
new 偏向于值类型变量
make服务于引用类型的变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值