Golang语言社区--Go语言基础第六节函数

大家好,我是Golang语言社区主编彬哥,本篇给大家带来的是关于Go语言中的函数。

函数定义

函数声明语句:

function 函数名(参数列表) (返回值列表) {
    // 函数体
}

注意:

1、  参数列表和返回值列表都是变量名在前,变量类型在后;

2、  Go函数支持多返回值,但并不是所有返回值都必须赋值,在函数返回时没有被明确赋值的返回值都会被设置为默认值。

3、  函数左起的花括号”{”不能另起一行,否则会报错;

 以一个简单的计算加法的函数为例:

func add(a int, b int) (ret int, err error) {
    if a<0 || b<0 {  // 假设这个函数只支持两个非负数的加法
        err = errors.New("Should be non-negative numbers!") 
        return
    }
    return a+b, nil
}

如果参数列表中若干个相邻的参数类型相同,则可以在参数列表中省略前面变量的类型声明,例如:

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

如果返回值列表中多个返回值的类型相同,也可以用同样的方式合并;另外,如果函数只有一个返回值,可以这样写:

func Add(a, b int) int {
  ...  
}

Go语言支持多重赋值,比如:

i, j = j, i

用于交换两个变量的值,在不支持多重赋值的语言中,交换两个变量的内容需要引入一个临时变量:

t = i; i = j; j = t

Go函数带回多个返回值时,可以使用多重赋值语句,将不同的返回值赋值给不同的变量,并且允许使用匿名变量("_")接受不需要使用的返回值,例如:

func GetName() (firstName, lastName, nickName string) {
    return "May", "Chan", "Chibi Maruko"
}

_, _, nickName := GetName

函数调用

函数调用非常方便,只要事先导入该函数所在的包,就可以调用了:

import "mymath"
c := mymath.Add(1,2)

注意:小写字母开头的函数只在本包内可见,大写字母开头的函数才能被其它包使用。

不定参数

例如:

func foo(args ...int) {  // 接受不定数量的参数,这些参数都是int类型
    for _, arg := range args {
        fmt.Println(arg) 
    }
}

foo(2,3,4)
foo(1,3,7,13)   

形如"...type"格式的类型只能作为函数的参数类型存在,并且必须是最后一个参数。

"...type"本质上是一个数组切片,也就是[]type,这也是为什么上面的参数args可以用for循环来获得每个传入的参数。

如果希望不定参数传任意类型,可以指定类型为interface{},如标准库中的fmt.Printf()的函数原型:

func Printf(format string, args ...interface{}) {
    ...
}

例如:

func foo(args ...interface{}) {
    for _, arg := range args {
        switch arg.(type) {
            case int:
                fmt.Println(arg, "is an int value.") 
            case string:
                fmt.Println(arg, "is a string value.") 
            case float32:
                fmt.Println(arg, "is a float32 value.") 
            default:
                fmt.Println(arg, "is an unknown type.") 
        }
    }
}

匿名函数与闭包

匿名函数可以直接赋值给一个变量,例如:

f := func(x, y int) int {
    return x+y
}

或者直接执行一个匿名函数:

func(ch chan int) {
    ch <- ACK
} (reply_chan)    // 花括号后面直接跟参数列表表示函数调用

闭包:当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部函数的局部变量。

a := func() (func()) {
    var i int = 10 
    return func(){
        fmt.Printf("i=%d\n", i)
        i++
    }
}

c1 := a() 
c2 := a() 
c1()        // 10
c1()        // 11
c1()        // 12
c2()        // 10

c1和c2是建立在同一个函数上,但作用在同一个局部变量的不同实例上的两个不同的闭包。

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 zhuanlan_guanli@qq.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏深度学习思考者

C++常见问题(二)——虚函数、类与结构、引用与值传递

一 文件输入输出的方式 C++定义了ifsteam、ofstream和fstream 3种类型以用来支持文件的输入输出。 二 异常 异常就是程序运行时出...

1726
来自专栏抠抠空间

函数 (一) 基础

一、函数的作用 函数可以让我们代码结构更清晰,而且避免了代码的重复,冗余,使一段代码或者功能可以反复的被调用,大大提高了开发效率 二、函数的定义 def 函数名...

2716
来自专栏互联网杂技

js的隐含参数(arguments,callee,caller)使用方法

在提到上述的概念之前,首先想说说javascript中函数的隐含参数: arguments arguments 该对象代表正在执行的函数和调用它的函数的参数。[...

3306
来自专栏butterfly100

python学习笔记-基础

一、python简介 python语言的特性就是简单优雅,写容易明了的代码,而且尽量写少的代码。python为我们提供了完善的基础代码库,包括网络、文件、DB、...

3829
来自专栏Golang语言社区

Golang指针与nil浅析

曾经听说过一句话,编程的本质就是指针和递归。那会刚开始编码,只是这两个的概念有个感性粗浅的认识。最早接触指针,莫过于C语言了,能否理解用好指针也成为一个合格C语...

2656
来自专栏Hongten

python开发_python关键字

The following identifiers are used as reserved words, or keywords of the languag...

663
来自专栏mathor

JAVA——基本数据类型

914
来自专栏JetpropelledSnake

Python入门之面向对象编程(二)python类的详解

本文通过创建几个类来覆盖python中类的基础知识,主要有如下几个类 Animal :各种属性、方法以及属性的修改 Dog :将方法转化为属性并操作的方法 Ca...

2779
来自专栏Android先生

Kotlin入门教程,快使用Kotlin吧

数组用Array类实现,和Java不同的地方在于,Array类有一个size属性表示数组长度,还有get和set方法,但是也可以使用array[position...

731
来自专栏一“技”之长

Swift讲解专题八——闭包 原

        Swift中的闭包是有一定功能的代码块,这十分类似于Objective-C中的block语法。Swift中的闭包语法风格十分简洁,其作用和函数的...

492

扫描关注云+社区