Go语言函数

函数是基本的代码块,用于执行某个任务。Go语言最少有个main()函数,可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。函数声明告诉了编译器函数的名称,返回类型和参数。Go语言标准库提供了多种可用的内置函数,例如:len()函数可以接受不同类型参数并返回该类型的长度。如果传入的是字符串,则返回字符串的长度;如果传入的是数组,则返回数组中包含的元素的个数。

函数定义

Go语言函数定义格式如下:

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

函数定义解析:

  • func:函数由fun开始声明;
  • function_name:函数名称,函数名和参数列表一起构成了函数签名;
  • parameter list:参数列表,参数就像一个占位符,当函数被调用时,可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序及参数个数。参数是可选的,也就是说函数也可以不包含参数。
  • return_types:返回类型,函数返回一系列值。return_types是该列值的数据类型,有些功能不需要返回值,这种情况下return_types不是必须的。
  • 函数体:函数定义的代码集合;

代码实例:

以下为max()函数的代码,该函数传入两个整形参数num1和num2,并返回这两个参数的最大值:

/* 函数返回两个数的最大值 */
func max(num1, num2 int) int {
/* 声明局部变量 */
var result int if (num1 > num2){
result = num1
}else {
result = num2
}
return result
}

函数调用

当创建函数时,定义了函数需要做什么,通过函数调用来执行指定任务。调用函数,向函数传递参数,并返回值,例如:

package main

import "fmt"

func main()  {
/* 定义局部变量 */
var a int = 100
var b int = 200
var ret int /* 调用函数并返回最大值 */
ret = max(a, b) fmt.Printf("最大值时:%d\n", ret)
} /* 函数返回两个数的最大值 */
func max(num1, num2 int) int {
/* 声明局部变量 */
var result int if (num1 > num2){
result = num1
}else {
result = num2
}
return result
}

以上实例在main()函数中调用max()函数,执行结果为:

最大值时:200

函数返回多个值

Go函数可以返回多个值,例如:

package main

import "fmt"

func swap(x, y string) (string, string) {
return y, x
} func main(){
a, b := swap("Mahesh", "Kumar")
fmt.PrintIn(a, b)
}

以上实例执行结果为:

Kumar Mahesh

函数参数

函数如果使用参数,该变量可称为函数的形参;形参就是像定义在函数体内的局部变量。调用函数,就可以通过两种方式来传递参数:

传递类型 描述
值传递 值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数
引用传递 引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数

默认情况下,Go语言使用的时值传递,即在调用过程中不会影响到实际参数。

函数用法

函数用法 描述
函数作为值 函数顶以后可作为值来使用
闭包 闭包是匿名函数,可在动态编程中使用
方法 方法就是一个包含了接收者的函数

值传递值

传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。默认情况下,Go语言使用的是值传递,即在调用过程中不会影响到实际参数,以下定义了swap()函数:

/* 定义相互交换值的函数 */
func swap(x, y int) int {
var temp int temp = x /* 保存x的值 */
x = y /* 将y的值赋给x */
y = temp /* 将temp值赋给y */ return temp;
}

使用值传递来调用swap()函数:

package main

import "fmt"

func main() {
/* 定义局部变量 */
var a int = 100
var b int = 200 fmt.Printf("交换前 a 的值为:%d\n", a)
fmt.Printf("交换前 b 的值为:%d\n", b) /* 通过调用函数来交换值 */
swap(a, b) fmt.Printf("交换后 a 的值为:%d\n", a)
fmt.Printf("交换后 b 的值为:%d\n", b)
} /* 定义相互交换值的函数 */
func swap(x, y int) int {
var temp int temp = x /* 保存x的值 */
x = y /* 将y的值赋给x */
y = temp /* 将temp值赋给y */ return temp;
}

以上代码执行结果为:

交换前 a 的值为 : 100
交换前 b 的值为 : 200
交换后 a 的值 : 100
交换后 b 的值 : 200

引用传递值

引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。引用传递指针参数传递到函数内,以下是交换函数swap()使用了引用传递:

/* 定义交换值函数 */
func swap(x *int, y *int){
var temp int
temp = *x /* 保持x地址上的值 */
*x = *y /* 将y值赋给x */
*y = temp /* 将temp值赋给y */
}

下面通过使用引用传递来调用swap()函数:

package main 

import "fmt"

func main(){
/* 定义局部变量 */
var a int = 100
var b int = 200 fmt.Printf("交换前 a 的值:%d\n", a)
fmt.Printf("交换前 b 的值:%d\n", b) /* 调用swap()函数
* &a 指向 a 指针,a变量的地址
* &b 指向 b 指针,b变量的地址
*/
swap(&a, &b) fmt.Printf("交换后 a 的值:%d\n", a)
fmt.Printf("交换后 b 的值:%d\n", b)
} func swap(x *int, y *int) {
var temp int
temp = *x /* 保存 x 地址上的值 */
*x = *y /* 将 y 值赋给 x */
*y = temp /* 将 temp 值赋给 y */
}

以上代码执行结果为:

交换前,a 的值 : 100
交换前,b 的值 : 200
交换后,a 的值 : 200
交换后,b 的值 : 100

函数作为值

Go语言可以很灵活的创建函数,并作为值使用。以下实例中我们在定义的函数中初始化一个变量,该函数仅仅是为了使用内置函数math.sqrt(),实例为:

package main

import (
"fmt"
"math"
) func main(){
/* 声明函数变量 */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
} /* 使用函数 */
fmt.Println(getSquareRoot(9)) }

以上代码执行结果为:

3

闭包

Go语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接是使用函数内的变量,不必申明。以下实例中,我们创建了函数getSequence(),返回另外一个函数,该函数的目的是在闭包中递增i变量,代码如下:

package main

import "fmt"

func getSequence() func() int {
i:=0
return func() int {
i+=1
return i
}
} func main(){
/* nextNumber 为一个函数,函数 i 为 0 */
nextNumber := getSequence() /* 调用 nextNumber 函数,i 变量自增 1 并返回 */
fmt.Println(nextNumber())
fmt.Println(nextNumber())
fmt.Println(nextNumber()) /* 创建新的函数 nextNumber1,并查看结果 */
nextNumber1 := getSequence()
fmt.Println(nextNumber1())
fmt.Println(nextNumber1())
}

以上代码执行结果为:

1
2
3
1
2

函数方法

Go语言中同时有函数和方法,一个方法就是包含了接受者的函数,接收者可以是命名类型或者结构体类型的一个值或一个指针,所有给定类型的方法数据该类型的方法集,其语法格式如下:

func (variable_name variable_data_type) function_name() [return_type] {
/* 函数体 */
}

下面定义一个结构体类型和该类型的一个方法:

package main

import (
"fmt"
) /* 定义结构体 */
type Circle struct {
radius float64
} func main() {
var c1 Circle
c1.radius = 10.00
fmt.Println("Area of Circle(c1) = ", c1.getArea())
} //该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
//c.radius 即为 Circle 类型对象中的属性
return 3.14 * c.radius * c.radius
}

以上代码执行结果为:

Area of Circle(c1) =  314

Go语言【第七篇】:Go函数的更多相关文章

  1. Python 学习 第七篇:函数1(定义、调用和变量的作用域)

    函数是把一些语句集合在一起的程序结构,用于把复杂的流程细分成不同的组件,能够减少代码的冗余.代码的复用和修改代码的代价. 函数可以0个.1个或多个参数,向函数传递参数,可以控制函数的流程.函数还可以返 ...

  2. C语言第七讲,函数入门.

    C语言第七讲,函数入门. 一丶了解面向过程和面向对象的区别. 为什么要先讲面向过程和面向对象的区别? 面向过程,就是什么都要自己做.  比如你要吃饭. 那么你得自己做饭. 面向对象, 面向对象就是我要 ...

  3. R语言学习 第四篇:函数和流程控制

    变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...

  4. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  5. 第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据O ...

  6. 第七篇 Integration Services:中级工作流管理

    本篇文章是Integration Services系列的第七篇,详细内容请参考原文. 简介在上一篇文章,我们创建了一个新的SSIS包,学习了SSIS中的脚本任务和优先约束,并检查包的MaxConcur ...

  7. 第七篇 SQL Server安全跨数据库所有权链接

    本篇文章是SQL Server安全系列的第七篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...

  8. Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)

    Python开发[第七篇]:面向对象   详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇)   上一篇<Python 面向对象(初级篇)> ...

  9. C 语言的可变参数表函数的设计

    在c语言中使用变长参数最常见的就是下面两个函数了: int printf(const char *format, ...); int scanf(const char *format, ...); 那 ...

随机推荐

  1. MySQL高级第一章——架构介绍

    一.简介 是一个经典的RDBMS,目前归属于Oracle 高级MySQL包含的内容: MySQL内核 SQL优化工程师 MySQL服务器的优化 各种参数常量设定 查询语句优化 主从复制 软硬件升级 容 ...

  2. python中通过datetime获取UTC时间ISO格式

    一个热点统计需求,需要限定一个时间范围,计算出该范围内的热点事件,相关数据则以UTC标准时间的ISO时间格式存在mongodb中,和服务器设置的时区UTC+8并不一致. 为了解决这个问题,直觉反应是在 ...

  3. LeetCode: 59. Spiral Matrix II(Medium)

    1. 原题链接 https://leetcode.com/problems/spiral-matrix-ii/description/ 2. 题目要求 给定一个正整数n,求出从1到n平方的螺旋矩阵.例 ...

  4. 容器云技术:容器化微服务,Istio占C位出道

    在精彩的软件容器世界中,当新项目涌现并解决你认为早已解决的问题时,这感觉就像地面在你的脚下不断地移动.在许多情况下,这些问题很久以前被解决,但现在的云原生架构正在推动着更大规模的应用程序部署,这就需要 ...

  5. phpanalysis提取关键字

    最近在开发一个文章模块功能,设计那边提出要给文章生成对应标签,用于文章关联推送,这里和大家分享一下实现过程: 这里需要用到PHPAnalysis,下载链接如下 链接:https://pan.baidu ...

  6. 【转】cocos2d-x如何优化内存的应用

    原地址:http://cblog.chinadaily.com.cn/blog-942327-4327173.html 注:自身以前也写过cocos2d-x如何优化内存的应用,以及内存不够的情况下怎么 ...

  7. opencv-学习笔记(3)

    opencv-学习笔记(3) 这章讲了 图像加法 opencv测试效率 IPYTHON测试效率 图像加法 cv2.add() 要求,两图片必须大小类型相同 然后是图像混合cv2.addWeighted ...

  8. POJ 2986 A Triangle and a Circle(三角形和圆形求交)

    Description Given one triangle and one circle in the plane. Your task is to calculate the common are ...

  9. HDU 2487 Ugly Windows(暴力)(2008 Asia Regional Beijing)

    Description Sheryl works for a software company in the country of Brada. Her job is to develop a Win ...

  10. vue学习笔记(五):对于vuex的理解 + 简单实例

    优点:通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护.使用vuex来引入外部状态管理,将业务逻辑切分到组件外,可以避免重复的从服务端抓取数据. 详情请参考官 ...