【Golang】函数篇

1、golang函数基本定义与使用

func 函数名 (形参列表) (返回值类型列表) {函数体return + 返回值列表
}

其中func用于表明这是一个函数,剩下的东西与其他语言的函数基本一致,在定义与使用的时候注意函数名、参数、返回值书写的位置即可。下面使用一个例子说明:求两个整数的和

func main() {fmt.Println("10 + 20 = ", getSum(10, 20))
}func getSum (num1, num2 int) int { //这里的返回值类型列表如果只有一个返回值,那么() 可以省略return num1 + num2
}

在这里插入图片描述
一些函数的使用细节:

  1. 函数与函数是并列的关系,因此不能嵌套定义
  2. 函数名的定义需要遵循标识符命名规范,
    即 首字符不能是数字
      函数名首字母大写表明该函数可以被本包文件和其他包文件使用
      函数名首字母小写表明只能被本包文件使用 其他包文件不能使用
  3. 形参列表 可以是若干个参数 0,1,2 ····
  4. 返回值类型列表:可以返回若干个,取决于函数的实现以及应用场景。对于返回值有多个的情况,如果在某一特定场景下,有些返回值不想使用,那么可以选择使用 "_"来告诉编译器这个返回值自动丢弃,不接收

2、golang函数传递参数相关细节

经典案例引入:实现一个函数exchangeNum函数,交换两个数的值

func exchangeNum(n1, n2 int) {var temp int = n1n1 = n2n2 = temp
}func main() {var num1 int = 100var num2 int = 200fmt.Printf("exchange before num1 is %v, num2 is %v \n", num1, num2)exchangeNum(num1, num2)fmt.Printf("exchange after num1 is %v, num2 is %v \n", num1, num2)
}

在这里插入图片描述
函数exchangeNum并没有将两个数完成交换。写出这样的代码根本原因是对参数的传递不够了解。下面展开说明。
 我们都知道一个程序在运行时会为其分配一块内存空间,这块内存空间在逻辑上被划分为堆区、栈区、代码区等区块。其中函数执行时会在栈区上为该函数分配一个栈帧,该栈帧在函数调用完毕后会被自动销毁。所以这个栈帧的生命周期是跟随函数的。
用此例来讲,main函数运行时,会产生main函数的栈帧,内部有两个变量num1=100, num2=200,调用exchangeNum的时候,会产生该函数的栈帧,然后该函数接收到两个参数n1=100, n2=200,在exchangeNum函数内,确实完成了这两个数值的交换,函数执行完n1, n2的值交换了。但是函数执行完exchangeNum函数栈帧也一同被销毁了,反观main函数的栈帧中num1 和num2的值依旧是没有发生变化。这也就是为什么执行完exchangeNum函数后两个变量的值并没有被交换的原因。

如何成功交换?

func exchangeNum(n1, n2 *int) {var temp int = *n1*n1 = *n2*n2 = temp
}func main() {var num1 int = 100var num2 int = 200fmt.Printf("exchange before num1 is %v, num2 is %v \n", num1, num2)exchangeNum(&num1, &num2)fmt.Printf("exchange after num1 is %v, num2 is %v \n", num1, num2)
}//方法2
func main() {var num1 int = 100var num2 int = 200num1, num2 = num2, num1
}

注意:

 golang函数不支持函数重载
 golang中支持可变参数 “…”

func test(args... int) { //test函数可以接受多个int类型的参数//在函数内部处理可变参数时将其当作切片来处理for(index := range args) {//相关处理,如打印}
}

 基本数据类型和数组默认都是值传递的,即进行值拷贝。在函数内修改不会影响到原来的值
 以值传递方式的数据类型,如果希望在函数内的改动能都影响到函数外,可以传入变量的地址&,函数内以指针的方式操作变量,从效果上看类似于引用传递

3、Go中函数可以当作数据类型

在Go语言中,函数也是一种数据类型,可以赋值给一个变量,那么该变量就是一个函数类型的变量。通过该变量可以对函数进行调用
在这里插入图片描述
既然函数是一种数据类型,因此在go中,函数可以作为形参并且被调用

func exchangeNum(n1, n2 *int) {var temp int = *n1*n1 = *n2*n2 = temp
}// 定义一个函数,能够接收函数作为形参
func forTest(flag bool, funcExNum func(*int, *int), num1, num2 *int) {if flag {funcExNum(num1, num2)}
}func main() {var num1 int = 100var num2 int = 200fmt.Printf("exchange before num1 is %v, num2 is %v \n", num1, num2)myexchange := exchangeNumfmt.Printf("myexchange 对应的类型是:%T, exchangeNum对应的类型是: %T \n", myexchange, exchangeNum)//此时使用 myexchange(&num1, &num2)等价于exchangeNum(&num1, &num2)myexchange(&num1, &num2)fmt.Printf("exchange after num1 is %v, num2 is %v \n", num1, num2)//此时使用forTest函数再次进行交换 并测试 函数雷总最为形参的使用forTest(true, myexchange, &num1, &num2)fmt.Printf("exchange after forTest: num1 is %v, num2 is %v \n", num1, num2)
}

在这里插入图片描述
为了简化数据类型定义,Go语言支持自定义数据类型
基本语法:type 自定义数据类型 数据类型

func main() {type myInt intvar num1 myInt = 100var num2 int = 40//注意:虽然是别名,但是在编译器看来,//myInt和int并不是同一种数据类型num2 = int(num1)
}
func exchangeNum(n1, n2 *int) {var temp int = *n1*n1 = *n2*n2 = temp
}
type myFun func(*int, *int)
// 定义一个函数,能够接收函数作为形参
func forTest(flag bool, funcExNum myFun, num1, num2 *int) {if flag {funcExNum(num1, num2)}
}

支持对函数返回值命名

//定义一个函数,返回两数之和 和 差
func dealNums(num1 int, num2 int) (int, int) {sum := num1 + num2sub := num1 - num2return sum, sub
}

这样的写法要求返回值与函数返回值类型列表需要一一对应
还有一种写法,显示地指出返回值

func dealNums(num1 int, num2 int) (sum int, sub int) {sub := num1 - num2sum := num1 + num2return
}

注意:这样写在函数内部代码执行完毕后,会将sub的最终值返回给函数返回值类型列表中的sub,sum也是如此

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/103019.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java开发之个人微信的二次开发

简要描述: 获取收藏详细信息 请求URL: http://域名地址/weChatFavorites/getFavItem 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数:…

算法通关村——滑动窗口高频问题

1. 无重复字符的最长子串 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 1.1 滑动窗口 找到最长字串需要找到字串的首尾位置…

win10系统配置vmware网络NAT模式

1,查看win10 IP地址:ipconfig 2, vmware设置:编辑>>虚拟网络编辑器>>点击添加网络(选择NAT模式) 3,虚拟机网络设置:点击VMware虚拟机>>设置>>网络适配器 4&#xff…

一加11/Ace2/10Pro手机如何实现全局120HZ高刷-游戏超级流畅效果

已经成功root啦。安卓13目前也一样支持LSPosed框架,如果你对LSP框架有需求,也可以使 自测120HZ刷新率诞生以后,很多小伙伴用上了就很难回来啦,一加11/Ace2/10Pro/9pro手 机厂商也对新机做了很多的适配,让我们日常使用起…

智能机器人:打造自动化未来的关键技术

文章目录 1. 智能机器人的基本概念2. 智能机器人的关键技术2.1 机器视觉2.2 机器学习与深度学习2.3 传感器技术 3. 智能机器人的应用领域3.1 制造业3.2 医疗保健3.3 农业3.4 服务业 4. 智能机器人的未来趋势4.1 自主决策能力的提升4.2 协作与互操作性4.3 个性化定制4.4 环境感知…

学习心得07:C#

之前也没有看过C#的书,C#的程序倒是搞了一些。好在项目不大,我又会套路。 C#很象是JAVA。好像就是JAVA出来之后,微软抄的。好东西就要学习,这不丢脸。 我倒是想,有没有办法把JAVA和C#进行映射,然后直接编译…

Vue2进阶篇学习笔记

文章目录 Vue2进阶学习笔记前言1、Vue脚手架学习1.1 Vue脚手架概述1.2 Vue脚手架安装1.3 常用属性1.4 插件 2、组件基本概述3、非单文件组件3.1 非单文件组件的基本使用3.2 组件的嵌套 4、单文件组件4.1 快速体验4.2 Todo案例 5、浏览器本地存储6、组件的自定义事件6.1 使用自定…

6.Xaml CheckBox控件

1.运行图片 2.运行源码 a.xaml 源码 <Grid Name="Grid1"><!--IsThreeState="True" 这个为true的时候,有三个状态 第三个状态为什么也没有--><CheckBox Name=

laravel系列(二) Dcat admin框架开发工具使用

开发工具可以非常好的帮助我们去快速的开发CURD等操作,但也是有部分框架有些不是太便捷操作,这篇博客主要为大家介绍Dcat admin的开发工具详细使用. 如何创建页面: 在联表我们首先要去.env文件中去找连接数据库方法: APP_NAMELaravel APP_ENVlocal APP_KEYbase64:thO0lOVlzj0…

Python Spyder下载、安装和使用教程

Spyder 是一款功能强大的 Python IDE&#xff08;集成开发环境&#xff09;&#xff0c;集编写、运行、调试 Python 程序于一身&#xff0c;可以安装到多个平台上&#xff0c;包括 Windows、Linux、Mac OS X。 图 1 Spyder Logo Spyder 除了拥有一般 IDE 普遍具有的编辑器、调…

基于Java+SpringBoot+Vue前后端分离论坛系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

软考:中级软件设计师:程序语言基础:表达式,标准分类,法律法规,程序语言特点,函数传值传址

软考&#xff1a;中级软件设计师:程序语言基础&#xff1a;表达式 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都…