首页 > 其他分享 >go语言函数

go语言函数

时间:2023-06-19 15:34:43浏览次数:35  
标签:return 函数 int fmt func go 返回值 语言

Go函数

由若干语句组成的语句块、函数名称、参数列表、返回值构成,它是组织代码的最小单元

完成一定的功能

函数的作用

结构化编程对代码的最基本的封装,一般按照功能组织一段代码

封装的目的为了复用,减少冗余代码

代码更加简洁美观、可读易懂

函数的分类

内建函数,如make、new、panic等

库函数,如math.Ceil()等

自定义函数,使用func关键字定义

函数定义

func 函数名(参数列表) [(返回值列表)]{
    函数体(代码块)
   [return 返回值]
}
// 这里[]表示其中的内容可有可无

函数名就是标识符,命名要求一样

定义中的参数列表称为形式参数,只是一种符号表达(标识符),简称形参

返回值列表可有可无,需要return语句配合,表示一个功能函数执行完返回的结果

函数名(参数列表) [(返回值列表)] 这部分称为函数签名

Go语言中形参也被称为入参,返回值也被称为出参

函数调用

函数定义,只是声明了一个函数,它不能被执行,需要调用执行

调用的方式,就是函数名后加上小括号,如有必要在括号内填写上参数

调用时写的参数是实际参数,是实实在在传入的值,简称实参,这个过程称为传实参,简称传参

如果定义了返回值列表,就需要配合使用return来返回这些值

// 函数定义
// x、y是形式参数,result是返回值
func add(a, b int) int {
 result := a + b // 函数体
 return result   // 返回值
}
func mod(a,b int) int {
 result := a / b
 return result
}
func main() {
 a := 4
 b := 5 
 out := add(a, b)  // 函数调用,可能有返回值,使用变量接收这个返回值
 fmt.Println(out)  // 对于Println函数来说,这也是调用,传入了实参out
 out = add(a, b) 
 fmt.Println(out)  
}

上面代码中,定义一个函数add,函数名是add,能接受2个整型参数,该函数计算的结果,通过return语句返回"返回值"实现;调用时,通过函数名add后加2个参数,返回值可使用变量接收; 函数名也是标识符,返回值也是值, 一般习惯上函数定义需要在调用之前,也就是说调用时,函数已经被定义过了。

函数调用原理

函数调用相当于运行一次函数定义好的代码,函数本来就是为了复用,试想你可以用加法函数,我也可 以用加法函数,你加你的,我加我的,应该互不干扰的使用函数。为了实现这个目标,函数调用的一般 实现,都是把函数压栈(LIFO),每一个函数调用都会在栈中分配专用的栈帧,局部变量、参数值、返回地值等数据都保存在这里。

如上面的代码,首先调用main函数,main压栈,接着调用add(4, 5)时,add函数压栈,压在main的栈帧 之上,add调用return,将add返回值保存在main栈帧的本地变量out上,add栈帧消亡,回到main栈帧。

 

 函数类型

package main
import "fmt"
func fn1()             {}
func fn2(i int) int     { return 100 }
func fn3(j int) (r int) { return 200 }
func main() {
 fmt.Printf("%T\n", fn1)
 fmt.Printf("%T\n", fn2)
 fmt.Printf("%T\n", fn3)
}
输出如下
func()
func(int) int
func(int) int

// 同一种签名的函数是同一种类型

返回值

返回值变量是局部变量

1、无返回值函数 在Go语言中仅仅一个return并不一定表示无返回值,只能说在一个无返回值的函数中,return表示无返 回值函数返回。

// 无返回值函数,可以不使用return,或在必要时使用return
func fn1() {
 fmt.Println("无返回值函数")
 return // return可有可无,如有需要,在必要的时候使用return来返回
}
t := fn1()         // 错误,无返回值函数无返回值可用
fmt.Println(fn1()) // 错误,无返回值函数无返回值可打印

2、返回一个值

Go语言中返回值不允许赋值给一个常量。

// 返回一个值,没有变量名只有类型。匿名返回值
func fn2() int {
 a := 100
 return a + 1 // return后面只要类型匹配就行
}
fmt.Println(fn2()) // 返回101
t := fn2()         // 返回101

// 返回一个值,有变量名和类型。命名返回值
func fn3() (r int) {
 r = 200
 return r - 1 // 类型匹配
}
fmt.Println(fn3())

//上面的函数还可以写成下面的形式
func fn3() (r int) {
 r = 200
 return // 如果返回的标识符就是返回值列表中的标识符,可以省略
}
fmt.Println(fn3())

3、返回多值

Go语言是运行函数返回多个值

// 返回多个值
func fn4() (int, bool) {
    a, b := 100, true
 return a, b
}
fmt.Println(fn4())
x, y := fn4() // 需要两个变量接收返回值

// 返回多个值
func fn4() (i int, b bool) {
 i, b = 100, true
 return // 如果和返回值列表定义的标识符名称和顺序一样,可省略
}
fmt.Println(fn4())
x, y := fn4() // 需要两个变量接收返回值

可以返回0个或多个值

可以在函数定义中写好返回值参数列表

可以没有标识符,只写类型。但是有时候不便于代码阅读,不知道返回参数的含义

可以和形参一样,写标识符和类型来命名返回值变量,相邻类型相同可以合并写

如果返回值参数列表中只有一个返回参数值类型,小括号可以省略

以上2种方式不能混用,也就是返回值参数要么都命名,要么都不要命名

return之后的语句不会执行,函数将结束执行;如果函数无返回值,函数体内根据实际情况使用return

return后如果写值,必须写和返回值参数类型和个数一致的数据

return后什么都不写那么就使用返回值参数列表中的返回参数的值

形式参数

 可以无形参,也可以多个形参

不支持形式参数的默认值

形参是局部变量

func fn1()                   {} // 无形参
func fn2(int)               {} // 有一个int形参,但是没法用它,不推荐
func fn3(x int)             {} // 单参函数
func fn4(x int, y int)       {} // 多参函数
func fn5(x, y int, z string) {} // 相邻形参类型相同,可以写到一起
fn1()
fn2(5)
fn3(10)
fn4(4, 5)
fn5(7, 8, "ok")

 可变参数

可变参数variadic。其他语言也有类似的被称为剩余参数,但Go语言有所不同。

可变参数收集实参到一个切片中

如果有可变参数,那它必须位于参数列表中最后。

func fn6(nums ...int) { // 可变形参
 fmt.Printf("%T %[1]v, %d, %d\n", nums, len(nums), cap(nums))
}
fn6(1)       // []int, [1]
fn6(3, 5)    // []int, [3 5]
fn6(7, 8, 9) // []int, [7 8 9]
func fn7(x, y int, nums ...int) {
 fmt.Printf("%d %d; %T %[3]v, %d, %d\n", x, y, nums, len(nums), cap(nums))
}
fn7(1, 2)       // 1 2; []int [], 0, 0
fn7(1, 2, 3)    // 1 2; []int [3], 1, 1
fn7(1, 2, 3, 4) // 1 2; []int [3 4], 2, 2

切片传递

可变参数限制较多,可以直接提供对应实参,封装成一个新的切片

可以使用使用切片传递的方式 切片... ,但是这种方式只能单独为可变形参提供实参,因为这是实参切片的header的复制

func fn6(nums ...int) { // 可变形参
 fmt.Printf("%T %[1]v, %d, %d\n", nums, len(nums), cap(nums))
}
var p = []int{1, 3, 5}
fmt.Printf("%p, %p, %v\n", &p, &p[0], p)
fn6(p...)

// 这种方式并不是把p这个切片分解了,然后传递给fn6函数,再封装成一个新的切片nums。而是相当于切片header的复制。
func fn7(x, y int, nums ...int) {
 fmt.Printf("%d %d; %T %[3]v, %d, %d\n", x, y, nums, len(nums), cap(nums))
}
p := []int{4, 5, 6}
fn7(p...) // 这在Go中不行,报奇怪的错,原因还是不能用在非可变参数上,就用4、5用在x、y上了
// 这个例子,本以为p被分解,4和5分别对应x和y,6被可变参数nums收集,但是这在Go语言中是错误的

 

标签:return,函数,int,fmt,func,go,返回值,语言
From: https://www.cnblogs.com/caibao666/p/17490704.html

相关文章

  • 函数Function
    函数的定义与调用Function  Tips:函数与子过程的区别是,函数可以返回值。如果一个函数不返回值,它与子过程并无区别,其中调用方式与子过程相同。无参子函数定义与调用//无参子函数的定义:Function[函数名]()As[返回值类型]//语句1//语句2//...//语句n......
  • Docker中安装MongoDb
    1.Dockercompose文件version:'3.1'networks:mongo:external:falseservices:mongo-express:image:mongo-expressrestart:alwaysports:-"8081:8081"environment:ME_CONFIG_MONGODB_ENABLE_ADMIN:t......
  • Understanding JavaScript Garbage Collection: Dive into Reference Counting and Ma
    JavaScript,theprogramminglanguageoftheweb,isoftenpraisedforitsabilitytohandlememorymanagementautomatically.TheJavaScriptengine'sgarbagecollectorplaysapivotalroleinthisprocess.Today,we'lltakeadeepdiveintotwom......
  • My SQL--------My SQL函数
    TRIM():去掉空格RTRIM():去掉右面空格LTRIM():去掉左侧空格UPPER():转大写SOUNDEX:将任何文本串转为描述其语音表示的芝麻油数字模式的算法。SOUNDEX考虑了类似的发音字符和音节,使得能对字符串进行发音比较......
  • 回文函数
    回文函数,学习到了strlen()函数在获取数组时是从str[1]开始计算的,要想从str[1]开始需要-1;#include<stdio.h>#include<string.h>intmain(){inti,j,n;charstr[80];//存储字符串printf("请输入字符串:\n");gets(str);//从输入读取字符串,并赋值给数组strn=strlen(str);fo......
  • R语言中根据列名删除指定的列
     001、删除a、d列a<-1:6b<-11:16c<-letters[1:6]d<-LETTERS[1:6]dat<-data.frame(a,b,c,d)datdat[,!names(dat)%in%c("a","d")]##删除a、d列 002、datlibrary(dplyr)select(dat,-c("a","......
  • Python3中的函数对象
    在Python中一切皆对象,函数也是一种对象,有相关的属性和方法。对于任意对象,我们可以用dir()函数来获取其内置的属性及方法名,例如:defadd(a:int,b:int=1)->int:"""加法函数"""returna+bprint(dir(add))运行结果如下:['__annotations__','__call__','_......
  • hugo 建立静态网站
    hugo简介https://gohugo.io什么是hogo?Hugo是Go编写的静态网站生成器,速度快,易用,可配置。Hugo有一个内容和模板目录,把他们渲染到完全的HTML网站。Hugo依赖于Markdown文件,元数据字体。用户可以从任意的目录中运行Hugo,支持共享主机和其他系统。Hugo只需要几分之一秒......
  • 强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间
    强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验1.强化学习核心概念强化学习(reinforcementlearning,RL):智能体可以在与复杂且不确定的环境进行交互时,尝试使所获得的奖励最大化的算法。动......
  • MySQL时间函数的选择
    Oracle中获取系统当前的时间,可以用sysdate、systimestamp等函数,在MySQL中,同样有类似的函数可以使用,碰巧看到eygle大神最近的文章,短短几行文字,就介绍了MySQL中获取系统当前时间的来龙去脉。在MySQL中,获得系统当前时间可以使用now()函数,这是最简单和应用最广的函数。除此之外,curre......