Golang中的函数

函数

在go语言中,函数的基本组成为:关键字func、函数名、参数列表、返回值、函数体和返回语句数组

  • 函数的定义

定义一个最简单的加法函数闭包

func Add(a int,b int)(ret int,err error){
    if a < 0 || b < 0{
        err = errors.New("这个函数只支持两个非负数的数字相加")
        return
    }

    return a + b,nil
}

若是参数列表中若干相邻的参数类型是相同的话,好比上述例子中的a和b,则能够在参数列表中省略前面的类型声明,例如:函数

func Add(a,b int)(ret int,err error){
    // ...     
}

若是返回值列表中多个返回值的类型相同,也能够用一样的方式合并code

若是函数只有一个返回值,也能够这样写:对象

func Add(a,b int) int{
    // ...    
}
  • 函数的调用

函数调用很是方便,只须要事先导入了该函数所在的包,就能够直接调用了,在go语言中,对函数命名有必定要求,只有大写开头的字母才能够被其余包调用,小写字母开头的函数只能在本包被调用作用域

例:假设Add函数在func1中开发

package main

import (
    "fmt"
    //导入包
    "functions/func1"
)

func main()  {
    a := 1
    b := 2
    // 经过包名调用函数
    ret,err := func1.Add(a,b)
    fmt.Println(ret,err)
}

函数的不定参数

  • 不定参数的类型

不定参数是值函数传入的参数个数为不定数量。io

func main(){
    // myfunc函数能够接收任意个int类型的参数
    myfunc(1,2,3,4,5,6,7,8)
}

// ... 表示不定参数
func myfunc(args ...int){
    for _,arg := range args {
        fmt.Println(arg)
    }
}

...type格式的类型只能做为函数的参数类型存在,而且必须是最后一个参数。。它是一
个语法糖(syntactic sugar),即这种语法对语言的功能并无影响for循环

从内部实现机理上来讲,类型...type本质上是一个数组切片,也就是[]type,这也是为
什么上面的参数args能够用for循环来得到每一个传入的参数。
假如没有...type这样的语法糖,开发者将不得不这么写:function

func myfunc2(args []int) {
    for _, arg := range args {
        fmt.Println(arg)
        }
}

从函数的实现角度来看,这没有任何影响,该怎么写就怎么写。但从调用方来讲,情形则完
全不一样:

myfunc2([]int{1, 3, 7, 13})
  • 任意类型的不定参数
func myfunc(args ...interface{}){
    // ...
}

用interface{}传递任意类型数据是go语言的惯例用法

匿名函数与闭包

  • 匿名函数

匿名函数由一个不带函数名的函数声明和函数体组成,如:

func(a,b int) bool {
    return a * b
}

匿名函数能够直接赋值给一个变量或者直接执行

// 赋值给一个变量
f := func(a,b int) int {
    return a * b
}

// 直接执行
func(a,b int) bool {
    return a * b
}(1,2)
  • 闭包
    • 闭包的基本概念:闭包是能够包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者
      任何全局上下文中定义,而是在定义代码块的环境中定义。要执行的代码块(因为自由变量包含
      在代码块中,因此这些自由变量以及它们引用的对象没有被释放)为自由变量提供绑定的计算环
      境(做用域)。
    • 闭包的价值:闭包的价值在于能够做为函数对象或者匿名函数,对于类型系统而言,这意味着不只要表示
      数据还要表示代码。支持闭包的多数语言都将函数做为第一级对象,就是说这些函数能够存储到
      变量中做为参数传递给其余函数,最重要的是可以被函数动态建立和返回。
    • go语言中的闭包
func main()  {
    var j int = 5
    //一个函数的返回值是一个函数的执行
    a := func()(func()) {
        var i int = 10
        return func() {
            fmt.Printf("i,j : %d  %d \n",i,j)
        }
    }()
    a()
    j *= 2
    a()

}
相关文章
相关标签/搜索