首页 > 编程语言 >学习go语言编程之函数

学习go语言编程之函数

时间:2023-08-12 23:58:06浏览次数:61  
标签:闭包 函数 int 编程 参数 func go 返回值

函数定义

函数的基本组成:关键字func,函数名,参数列表,返回值,函数体,返回语句。
示例如下:

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 // 支持多重返回值
}

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

// 参数列表中a,b的类型相同,省略了a参数的类型声明
func Add(a, b int) (ret int, err error)  {
	// ...
}

如果返回值列表中多个返回值的类型相同,也可以使用同样的方式合并。

如果函数返回值只有一个,不用声明返回值变量名:

// 函数只有一个返回值,不用声明返回值变量名
func Add2(a, b int) int {
	// ...
}

函数调用

在调用函数前,需要导入函数所在的包:

import "mymath"// 假设Add被放在一个叫mymath的包中
c := mymath.Add(1, 2)

注意: Golang中函数名字的首字母大小写不仅仅是风格,更直接体现了该函数的可见性。
规则:小写字母开头的函数只在本包内可见,大写字母开头的函数才能被其他包使用。这个规则也适用于类型和变量的可见性。

不定参数

不定参数是指函数的参数个数为不定数量。

不定参数类型

将函数定义为接收不定参数类型:

func myFunc(args ...int) {
	for _, arg := range args {
		fmt.Print(arg, " ")
	}
	fmt.Println()
}

调用:

// 传递给函数的参数个数不固定
myFunc(1)
myFunc(1, 2)

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

不定参数的传递

假设有一个变参函数myFun2

func myFun2(args ...int) {
	// ...
}

如下示例展示了如何向其传递变参:

func myFunc(args ...int) {
    // 按原样传递
	myFun2(args...)
    // 传递参数片段
	myFun2(args[1:]...)
}

任意类型的不定参数

如果希望传递任意类型的参数,可以指定类型为interface{}
示例:

// 不定参数类型
func myPrintf(args ...interface{})  {
	for _, arg := range args {
		switch arg.(type) {
		case int:
			fmt.Println(arg, "is an integer")
		case string:
			fmt.Println(arg, "is a string")
		case int64:
			fmt.Println(arg, "is a int64")
		default:
			fmt.Println(arg, "is an unknown type")
		}
	}
}

func main() {
	var v1 int = 1
	var v2 int64 = 2
	var v3 string = "hello"
	var v4 float32 = 1.23

    // 调用不定参数类型函数
	myPrintf(v1, v2, v3, v4)
}

输出:

1 is an integer
2 is a int64
hello is a string
1.23 is an unknown type

多返回值

Golang函数或者成员的方法可以有多个返回值,这个特性能够使我们写出比其他语言更优雅、更简洁的代码。
比如File.Read()函数就可以同时返回读取的字节数和错误信息,如果读取文件成功,则返回值中的n为读取的字节数,err为nil,否则err为具体的出错信息:

func (file *File) Read(b []byte) (n int, err Error)

还可以给返回值命名,就像函数的输入参数一样。
返回值被命名之后,它们的值在函数开始的时候被自动初始化为空。
在函数中执行不带任何参数的return语句时,会返回对应的返回值变量的值。

Golang并不需要强制命名返回值,但是命名后的返回值可以让代码更清晰,可读性更强,同时也可以用于文档。

如果调用方调用了一个具有多返回值的方法,但是却不想关心其中的某个返回值,可以简单地用一个下划线“_”来跳过这个返回值。
比如下面的代码表示调用者在读文件的时候不想关心Read()函数返回的错误码:

n, _ := f.Read(buf)

匿名函数和闭包

匿名函数是指不需要定义函数名的一种函数实现方式。

匿名函数

在Golang中,函数可以像普通变量一样被传递或使用,可以随时在代码里定义匿名函数。

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

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

匿名函数可以直接赋值给一个变量或者直接执行:

// 定义匿名函数并赋值给变量
f := func(x, y int) int {
    return x + y
}

// 调用函数
f(1, 2)

// 匿名函数的花括号后面直接跟参数列表表示调用匿名函数
func(x, y int) int {
    return x + y
}(1,2)

闭包

Golang的匿名函数是一个闭包。
Golang中的闭包同样也会引用到函数外的变量,闭包的实现确保只要闭包还被使用,那么被闭包引用的变量会一直存在。

// 闭包
var j int = 5
a := func()  {
    var i int = 10
    fmt.Printf("i, j: %d, %d\n", i, j)
}
a()
j *= 2
a() // 在这里还会调用闭包函数,被它引用的外部变量j一直存在,所以其只会在两次闭包调用时不同

输出:

i, j: 10, 5   # 第一次调用闭包函数时,变量j的值未变化
i, j: 10, 10  # 第二次调用闭包函数时,变量j的值已经发生变化

标签:闭包,函数,int,编程,参数,func,go,返回值
From: https://www.cnblogs.com/nuccch/p/17625879.html

相关文章

  • 8-12|go语言之输入
    在Go语言中,输入主要是通过标准库中的包来实现的。常用的包有`fmt`和`bufio`。以下是一些基本的Go输入方法:1.**使用`fmt.Scan()`和相关函数**:    `fmt.Scan()`,`fmt.Scanln()`,和`fmt.Scanf()`是用于从标准输入读取值的常用方法。    ```go  ......
  • 数论函数小计
    1.基础数论函数定义:数论函数,就是值域为整数(陪域为复数)的函数狄利克雷卷积两个数论函数的狄利克雷卷积是一个新的函数比如\(f(n)\),\(g(n)\)它们的卷积就是\(f*g\)怎么卷呢?定义:\(\large{(f*g)(n)=\sum\limits_{d|n}f(n)g(n/d)}\)举个例子:\((f*g)(12)=f(1)*g......
  • Django实现文件上传、文件列表查看、修改、限流和日志记录
    Django实现文件上传、文件列表查看、修改、限流和日志记录本章先简单实现文件的上传,后续会将标题的功能一一添加上去实现,并且给出远程服务器的不同连接方式【密码和秘钥】,欢迎继续关注。安装了Django框架pipinstalldjango 创建一个Django项目django-adminstartproj......
  • 线性筛与欧拉函数
    很萌很可爱!就是把纸质笔记上letex写在这里有亿点慢线性筛埃氏筛,\(O(n\log\logn)\),思路是⌈标记所有质数的倍数⌋这样每个合数可能会被标记好几次,我们改进一下,让每个合数只有一种被标记的方式,即⌈最小质因子*常数⌋具体而言,⌈枚举\(2\tox\)把当前数\(i\)跟......
  • 学习go语言编程之常量
    什么在常量在Golang中,常量是指在编译期就已知且不可改变的值。字面常量在程序中硬编码的常量值被称为字面常量,如:-12//整数类型常量3.1415926//浮点类型常量3.2+12i//复数类型常量true//布尔类型常量"foo"//字符串常量常量定义使用关键字con......
  • 学习go语言编程之数据类型
    数据类型概述Golang语言内置了如下基础数据类型:布尔类型:bool整型:int8,unit8,int16,uint16,int32,uint32,int64,uint64,int,uint,uintptr浮点类型:float32,float64复数类型:complex64,complex128字符串:string字符类型:rune错误类型:error同时,Golang还支持如下复合类型:指针:pointer数组......
  • 学习go语言编程之流程控制
    Golang支持如下4种流程控制语句:条件语句:if,else和elseif选择语句:switch,case和select循环语句:for,range跳转语句:goto条件语句示例代码:a:=3ifa<5{fmt.Println(a,"litterthan5")}else{fmt.Println(a,"notlitterthan5")}关于条件语句,要注意以下......
  • 区间半群查询与 Ackermann 函数
    最近在思考半在线卷积的复杂度有没有可能进一步优化,决定先理清类似的问题以寻求经验.一区间合并如果询问的时候不能进行半群运算,显然我们需要在预处理阶段处理所有答案,必须进行\(O(n^2)\)次计算.二区间合并如果询问的时候可以进行一次半群运算,则可以把序列每次在中......
  • Golang之旅——内存管理
    转载放在最前一文带你了解,虚拟内存、内存分页、分段、段页式内存管理[Golang三关-典藏版]一站式Golang内存洗髓经|Go技术论坛刘丹冰Aceld感谢以上文章作者,收获满满......
  • 无涯教程-Perl - package函数
    描述此函数将当前符号表的名称更改为NAME。包名称的范围一直到封闭块的末尾。如果省略NAME,则没有当前包,并且所有函数和变量名称都必须使用其完全限定的名称声明。语法以下是此函数的简单语法-packageNAMEpackage返回值此函数不返回任何值。要了解package关键字,......