go语言基础-----03-----流程控制、函数、值传递、引用传递、defer函数

2023-11-20

1 流程控制

这里只讲"for range 语句"这个关键字,主要用于遍历,用来遍历数组、slice、map、chan。
例如:

package main

import (
	"fmt"
)

func main() {
	str := "hello world,中国"
	for i, v := range str {
		fmt.Printf("index[%d] val[%c]\n", i, v)
	}
}

在这里插入图片描述

2 函数

函数实际上在上一节也有提过。

2.1. 声明语法:func 函数名 (参数列表) [(返回值列表)] {}

例如

func add(){
}

2.2. golang函数特点:

a. 不支持重载,一个包不能有两个名字一样的函数。
b.函数也是一种类型,一个函数可以赋值给变量。
c. 可以是匿名函数。
d. 多返回值。

函数的例子1,形参带有回调函数。

package main

import "fmt"

// 定义一个函数指针,和C/C++的typedef一样
type op_func func(int, int) int

func add(a, b int) int {
	return a + b
}

func sub(a, b int) int {
	return a - b
}

// 定义一个函数,这个函数的形参带有回调函数
func operator(op op_func, a, b int) int {

	return op(a, b)
}

func main() {
	var a, b int
	add(a, b)

	var c op_func // 自定义类型的变量c。
	c = add       // 将函数赋值给变量c。
	fmt.Println(add)
	fmt.Println(c)

	sum := operator(c, 100, 200)
	fmt.Println(sum)
}

函数的例子2,函数的返回值若只写return,则会按照函数的返回值声明进行返回。

package main

import "fmt"

func calc(a, b int) (sum int, avg int) {
	sum = a + b
	avg = (a + b) / 2
	return // 这里虽然没返回,但是实际上会按照上面的返回值的声明进行返回。相当于语句:return sum, avg
}

func main() {
	sum, avg := calc(10, 20)
	fmt.Println("sum: ", sum, ", avg: ", avg)
}

在这里插入图片描述

2.3. 函数参数传递方式(值传递、引用传递):

1). 值传递。
2). 引用传递。

注意1:无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能越低。
并且由于地址拷贝,它们会共用同一片内存,所以在函数内部修改返回后,回到调用函数再进行使用,该变量也是发生变化了的。

注意2:map、slice、chan、指针、interface默认以引用的方式传递。

2.4. 命名返回值的名字

看上面的函数的例子2。

2.5. _标识符,用来忽略返回值

func calc(a, b int) (sum int, avg int) {
	sum = a + b
	avg = (a +b)/2
	return
}

func main() {
	sum, _ := calc(100, 200)
}

2.6. 可变参数:

func add(arg…int) int {					//0个或多个参数
} 
func add(a int, arg…int) int {			// 1个或多个参数
} 
func add(a int, b int, arg…int) int { 	// 2个或多个参数
}

注意:其中arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断传递参数的个数,但是len(arg)的范围只是arg,不包含已经确定的参数,例如上面代码的"1个或多个参数",前面的a形参是不在这个长度len范围。

例如:

package main

import "fmt"

func add(a int, arg ...int) int {
	var sum int = a
	for i := 0; i < len(arg); i++ {
		sum += arg[i]
	}

	return sum
}

func concat(a string, arg ...string) (result string) {

	result = a
	for i := 0; i < len(arg); i++ {
		result += arg[i]
	}

	return
}

func main() {
	sum := add(10, 3, 3, 3, 3)
	fmt.Println(sum)

	res := concat("hello", " ", "world")
	fmt.Println(res)
}

在这里插入图片描述

3. defer用途:

1. 当函数返回时,执行defer语句。因此,可以用来做资源清理。
2. 多个defer语句,按先进后出的方式执行,与栈的原理一样。
3. defer语句中的变量,在defer声明时就决定了它的值。

3.1 常见清理资源的操作:

// 1 关闭文件句柄:
func read() {
	file := open(filename)
	defer file.Close()
	//文件操作
}

// 2. 锁资源释放
func read() {
	mc.Lock()
	defer mc.Unlock()
	//其他操作
}

// 3. 数据库连接释放
func read() {
	conn := openDatabase()
	defer conn.Close()
	//其他操作
}

3.2 defer的例子1:

package main

import "fmt"

// 定义一个全局的函数变量
var (
	result = func(a1 int, b1 int) int {
		return a1 + b1
	}
)

func test(a, b int) int {
	// 这里定义了一个局部的函数变量,所以实际上test和全局变量result的作用是一样的
	result := func(a1 int, b1 int) int {
		return a1 + b1
	}

	return result(a, b)
}

func main() {
	// 1. 调用全局函数变量
	fmt.Println(result(100, 200))

	var i int = 0

	defer fmt.Println(i)        // 有defer的语句会最后执行,但是用到的变量在这里声明时就决定了,所以这里最后输出:0
	defer fmt.Println("second") // 先进后出,所以两个defer最后必定是输出:second后,再输出 0

	i = 10
	fmt.Println(i)
}

在这里插入图片描述

3.3 例子2:

func f() {
	// 相当于执行了5次defer,然后根据先进后出的情况,那么就是输出 4 3 2 1 0
	for i := 0; i < 5; i++ {
		defer fmt.Printf("%d ", i)
	}
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go语言基础-----03-----流程控制、函数、值传递、引用传递、defer函数 的相关文章

  • 在 Golang Server 中接受持久的 tcp 连接

    我正在尝试使用 Go 并且想创建一个 TCP 服务器 我可以通过 telnet 访问该服务器 发送命令并接收响应 const CONN HOST localhost CONN PORT 3333 CONN TYPE tcp func mai
  • 如何获取字段类型的零值

    我有一个包含许多字段的结构 我已经弄清楚如何使用反射提取字段名称 值和标签信息 我还想做的是确定字段的值是否与字段的默认值不同 目前 我有这个 有效 但有点臭 qsMap make map string interface var defa
  • 如何访问 Go 中的嵌套模块(子模块)?

    去版本 1 12 9 这是一个简单演示项目的结构 所以我们有一个模块domain 其中包含两个模块 activity and person 我想将域与主文件中的所有嵌套模块一起使用 gt 模块 go 我知道如何导入domain主要在go m
  • 如何在Go中从interface{}解组到interface{}

    我的系统中有多个通过 RPC 进行通信的节点 我正在尝试通过 RPC 将 map string interface 发送到另一个节点 发送方使用 json Marshal 接收方使用 json Unmarshal 来获取地图 假设在发送方
  • 如果覆盖率低于一定百分比,则单元测试失败

    我制作了一个执行的 makefilego test cover 是否有可能失败make unit tests如果覆盖范围低于 X 则命令 我该怎么做呢 您可以使用TestMain在你的测试中做到这一点 TestMain 可以充当测试的自定义
  • 为什么我不能执行 fmt.Sprintf("%d.%d.%d.%d", a...)?

    我正在学习 Go 但我一直坚持 Go 之旅 exercise stringer go https tour golang org methods 7 https tour golang org methods 7 这是一些代码 type I
  • 通过 API Gateway 使用表单数据将图像发布到 Lambda 函数会导致文件无效

    I ve a 用 Go 编写的 Lambda 函数 https github com mhausenblas imgn blob master functions app uploadimg main go应该允许图像文件上传 通过 HTM
  • 在 Go 中修改导入的库

    我的问题 弹性节拍 https www elastic co products beats是一个用 Go 编写的日志传送程序的开源项目 它具有多种日志输出功能 包括控制台 Elasticsearch 和 Redis 我想将我自己的输出添加到
  • 具有多个等待组的管道中通道范围内的死锁

    我正在练习通过同时将计算分为 100 组来计算阶乘的挑战 我解决了 WaitGroups 上的很多问题 但仍然处于calculateFactorial函数我在通道部分的范围上陷入了僵局 希望有人能指出这个问题 谢谢 package main
  • 如何通过模板中的变量访问对象字段?

    我有一个嵌套循环 columns columns range dx dataList range c columns index dx c end end dataList是orm模型数组 和ID Title字段 那么columns is
  • 在 Go 中执行字节数组

    我正在尝试在 Go 程序中执行 shellcode 类似于使用其他语言执行此操作的方式 示例 1 C 程序中的 Shellcode https stackoverflow com questions 16626857 shellcode i
  • 在 Go 中生成随机、固定长度的字节数组

    我有一个字节数组 固定长度为4 token make byte 4 我需要将每个字节设置为随机字节 我怎样才能以最有效的方式做到这一点 这math rand就我而言 方法不提供随机字节函数 也许有一种内置的方法 或者我应该生成一个随机字符串
  • 初始化嵌套匿名结构

    我有一个 json 作为 fields time id status customerId additionalDetail pageInfo start 0 rows 1000 我想将我的结构编组到上面的 json 并创建如下结构 typ
  • 从 []byte 到 char*

    我想包装一个 C 函数 它需要一个char 指向非空字节缓冲区 的第一个元素 我正在尝试使用 CGo 将其包装在 Go 函数中 以便我可以将其传递给 byte 但我不知道如何进行转换 C 函数签名的简化版本是 void foo char c
  • Go中如何自定义http.Client或http.Transport超时重试?

    我想实现一个自定义http Transport对于标准http Client 如果客户端超时 它将自动重试 附 由于某种原因 习俗http Transport is a 一定有 我已经查过了hashcorp go retryablehttp
  • 为什么奇数的切片容量与偶数的切片行为不同

    我注意到 当容量为奇数时 切片的容量会以不同的方式表现 更具体地说 当向切片添加元素时 切片的容量为doubled当原始容量为偶数时 但当原容量为奇数时 容量为增加一 然后加倍 例子 s make int 28 28 s append s
  • Go io.Pipe 的缓冲版本

    有缓冲版本吗io Pipe https golang org pkg io Pipe 在标准库或第三方库中 在我推出自己的库之前 上下文 我正在尝试使用这个解决方案 https stackoverflow com a 36229262 15
  • 如何分析 VSCode 中函数的性能

    我用 C Golang 编写了一个程序 如何找到占用最高 CPU 周期的函数 目的是提高正在执行的程序的性能 2021 年 10 月 金香儿哈娜 https github com hyangah宣布 tweet https twitter
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • 如何在 Go 中解组具有多个项目的简单 xml?

    我想从以下 xml 中获取人物 People 的一部分

随机推荐

  • 软件项目管理的平衡原则和高效原则

    1 平衡原则 在我们讨论软件项目为什么会失败时 列出了很多的原因 答案有很多 如管理问题 技术问题 人员问题等等 但是 有一个根本的问题是最容易被忽视的 也是软件系统的用户 软件开发商 销售代理商最不愿证实的 那就是 需求 资源 工期 质量
  • 计算机网络 网络层——IP数据报 详记

    IP 数据报的格式 一个 IP 数据报由首部和数据两部分组成 首部的前一部分是固定长度 共 20 字节 是所有 IP 数据报必须具有的 在首部的固定部分的后面是一些可选字段 其长度是可变的 IP数据报首部的固定部分中的各字段 版本 占4位
  • 信号量机制

    简介 信号量是一种数据结构 信号量的值与相应资源的使用情况有关 信号量的值由P V操作改变 常用信号量 整型信号量 整型信号量S的等待 唤醒机制 P V操作 wait S while S lt 0 do no op s signal S S
  • python字符串与列表

    字符串 字符串定义 输入输出 定义 切片是指对操作的对象截取其中一部分的操作 适用范围 字符串 列表 元组都支持切片操作 切片的语法 起始下标 结束 步长 字符串中的索引是从 0 开始的 最后一个元素的索引是 1 字符串的常见操作 查找 f
  • centos7搭建ftp服务器及ftp配置讲解

    ftp 即文件传输 它是INTERNET上仍然常用的最老的网络协议之一 它为系统提供了通过网络与远程服务器传输的简单方法 FTP服务器包的名称为vsftpd 一 vsftpd安装 并简单配置启动 安装 很简单 一句话 yum install
  • Socket接收数据耗时

    1 遇到问题 首先说明一下我遇到的问题 服务端传递Byte数组 长度在900w 客户端接收时会耗时10s 我的代码是这样的 2 Socket缓冲区 http t zoukankan com bigberg p 7747419 html 每个
  • 即刻掌握python格式化输出的三种方式 (o゜▽゜)o☆

    目录 1 f 转化的格式化输出方式 2 格式化输出的方法 3 format 格式化输出的方法 1 f 转化的格式化输出方式 只需要在我们要格式化输出的内容开头引号的前面加上 f 在字符串内要转义的内容用 括起来即可 模板 print f x
  • 企业微信登录-前端实现

    企业微信登录 企业微信登录 前端具体实现 下面代码中配置项的字段具体用途说明可以阅读企业微信开发者说明文档 我们通过提供的企业微信登录组件来进行站内登录 下面是我封装的登录组件以及使用方法 weChatLogin vue 封装的组件
  • hudi-hive-sync

    hudi hive sync Syncing to Hive 有两种方式 在hudi 写时同步 使用run sync tool sh 脚本进行同步 1 代码同步 改方法最终会同步元数据 但是会抛出异常 val spark SparkSess
  • spring:AOP面向切面编程+事务管理

    目录 一 Aop Aspect Oriented Programming 二 springAOP实现 1 XML实现 2 注解实现 三 spring事务管理 一 Aop Aspect Oriented Programming 将程序中的非业
  • NLP中BERT在文本二分类中的应用

    最近参加了一次kaggle竞赛Jigsaw Unintended Bias in Toxicity Classification 经过一个多月的努力探索 从5月20日左右到6月26日提交最终的两个kernel 在public dataset
  • 单目标追踪——【Transformer】MixFormer: End-to-End Tracking with Iterative Mixed Attention

    目录 文章侧重点 网络结构 MAM Mixed Attention Module MixFormer 论文 代码 文章侧重点 本文的出发点是认为现有的多阶段Siamese追踪框架 特征提取 特征融合 边界框预测 的前两步 特征提取 特征融合
  • 搬运工~看到一个很有意思的python程序

    coding utf 8 import 二炮 Class 核武 二炮 二炮任务 默认小日本 def init self self 核武状态 二炮 NB status def status self return self 核武状态 def
  • Python编程中的for循环语句学习教程

    本文来源于公众号 csdn2299 喜欢可以关注公众号 程序员学府 这篇文章主要介绍了Python编程中的for循环语句学习教程 是Python入门学习中的基础知识 需要的朋友可以参考下 Python for循环可以遍历任何序列的项目 如一
  • 12306 图形验证码闲谈

    验证码是一个非常有意思的问题 它的目的是区分输入者是人还是机器 这个问题本质上是一个图灵测试 推荐电影 模仿游戏 验证码即是一种简单高效的验证方法 由CMU的教授于2000年左右创造 后来此牛人又将零星的验证码收集起来 转化为巨大的生产力
  • 养生产品如何进行线上推广?产品线上推广的渠道有哪些?

    随着时间的推移 中国人口老龄化越来越多 并且由于生活水平不断提高 居民收入富裕 越来越多的人对于自身健康问题越来越关注 健康养身行业将会迎来蓬勃发展 养生行业内的企业公司现在可以提前进行市场布局 抓住时机发展壮大 那么 健康养生产品如何进行
  • Virtual Box安装时出现严重错误的解决方法

    之前安装了Vitual Box 卸载后尝试了网上很多方法 查了很多资料 最后成功解决 记录一下方法 如下情况 1 我们先下载Mirosoft Visual C 2019 输入如下网址 选择第一个内容 这里我们向下划 找到如下图 下载对应的版
  • 关于conda使用环境未被激活问题

    若在安装Anaconda之后 出现 Warning This Python interpreter is in a conda environment but the environment has not been activated 那
  • 【Liunx】进程控制和父子进程

    文章目录 1 进程和程序 1 1进程和程序的概念 1 2单道和多道程序设计 1 3进程状态的转换 1 3 1进程的状态切换 1 3 2MMU 内存管理单元的作用 1 3 4PCB 进程控制块 的认识 1 3 5获取环境变量 2 控制进程 2
  • go语言基础-----03-----流程控制、函数、值传递、引用传递、defer函数

    1 流程控制 这里只讲 for range 语句 这个关键字 主要用于遍历 用来遍历数组 slice map chan 例如 package main import fmt func main str hello world 中国 for