Golang学习Day2
Go语言中的函数
go语言中函数特性
go语言有三种函数:普通函数、匿名函数(没有名称的函数)方法(定义在struct上的函数)。receiver
go语言中不运算函数重载(overload),也就是说不允许函数同名
go语言中的函数不能嵌套,但是可以嵌套匿名函数
函数是一个值,可以将函数赋值给变量,使得这个变量也成为函数
函数可以作为参数传递给另一个函数
函数的返回值可以是另一个函数
函数调用的时候,如果有参数传递给函数,则先拷贝参数的副本,再将副本传递给函数
函数参数可以没有名称
go语言中函数的定义和调用
函数在使用之前必须先定义,可以调用函数来完成某个任务,函数可以重复调用,从而达到代码的复用
func function_name([parameter_list])[return_types]{函数体
}
package mainimport "fmt"func sum(a int, b int) (res int) {res = a + breturn res
}
func main() {res := sum(1, 2)fmt.Printf("res: %v\n", res)
}
package mainimport "fmt"func compare(a int, b int) (max int) {if a > b {max = a} else {max = b}return max
}
func main() {res := compare(1, 2)fmt.Printf("res: %v\n", res)
}go语言中的return
没有返回值
有一个返回值 (例如上面的求和以及比较两个数的大小的函数)
存在多个返回值,且在return中指定返回的内容
多个返回值,返回值名称没有被使用
return覆盖命名返回值,返回值名称没有被使用
package mainimport "fmt"func test() {fmt.Print("testing...")
}
func main() {test()
}
package mainimport "fmt"func test() (string, int) {name := "Y4y17"age := 24return name, age
}
func main() {name, age := test()fmt.Printf("name: %v\n", name)fmt.Printf("age: %v\n", age)
}package mainimport "fmt"func test() (name string, age int) {name = "Y4y17"age = 24return //相当于return name,age
}
func main() {name, age := test()fmt.Printf("name: %v\n", name)fmt.Printf("age: %v\n", age)
}package mainimport "fmt"func test() (name string, age int) {n := "Y4y17" //重新定义了n和a,那么返回的时候只能返回n和a,而不是name和agea := 24 //这种情况一般不这样写,一般就是直接去掉返回值中的name和age,只保留类型return n, a
}
func main() {name, age := test()fmt.Printf("name: %v\n", name)fmt.Printf("age: %v\n", age)
}Go中经常会使用其中一个返回值作为函数是否执行成功、是否有错误信息的判断条件;例如return value,exists、return value,ok、return value,err等
当函数的返回值过多的时候,例如有4个以上的返回值,应该将这些返回值收集到容器中,然后以返回容器的方式去返回。例如,同类型的返回值可以放进slice中,不同类型的返回值可以放进map中。
当函数有多个返回值的时候,如果其中某个或者是某几个返回值不想用,可以通过下划线_来丢弃这些返回值。
函数的参数
package mainimport "fmt"func test(a int) {a = 200 //test函数中修改变量a的值为200
}
func main() {a := 5 //定义变量a的值为5test(a)fmt.Printf("a: %v\n", a)//输出a的值,依然还是5
}数组、切片、指针都是传地址,也就是传址的方式;
package mainimport "fmt"func test(s []int) {s[2] = 17
}
func main() {s := []int{1, 2, 3, 4}test(s)fmt.Printf("s: %v\n", s)//输出的结果为s: [1 2 17 4]
}变长参数
package mainimport "fmt"
//其实就像是传递了一个数组或者是切片
func test(args ...int) {for _, v := range args {fmt.Printf("v: %v\n", v)}
}
func main() {test(1, 2, 3, 4, 5, 6, 7)
}package mainimport "fmt"func test(name string, b bool, args ...int) {fmt.Printf("name: %v\n", name)fmt.Printf("b: %v\n", b)for _, v := range args {fmt.Printf("v: %v\n", v)}
}
func main() {test("Y4y17", true, 1, 2, 3, 4, 5, 6, 7)
}函数中的type关键字
相当于在c语言中的typedef关键字,说白了就是对现有的数据类型起了一个别名
package mainimport "fmt"func add(a int, b int) int {return a + b
}
func comp(a int, b int) int {if a > b {return a} else {return b}
}
func main() {type f func(a int, b int) intff := addr := ff(1, 2)fmt.Printf("r: %v\n", r)ff = compr = ff(1, 2)fmt.Printf("r: %v\n", r)
}Go高阶函数
函数作为参数
package mainimport "fmt"func test(name string, f func(string)) { f(name)
}
func sayHello(name string) {fmt.Printf("Hello: %v\n", name)
}
func main() {test("Y4y17", sayHello)
}//test函数接受两个参数,分别是string类型的name和func(函数类型)的f(函数名)
sayHello函数接受一个参数,即string类型的name,主函数中调用test函数,传递参数Y4y17,和sayHello函数名;那么test函数中便会执行sayHello("Y4y17")
函数作为返回值
package mainimport "fmt"func add(a int, b int) int {return a + b
}
func sub(a int, b int) int {return a - b
}
func test(operate string) func(int, int) int {//test函数接受一个string类型的参数operate,test函数返回值是一个函数,该函数有两个int类型的参数并且返回值也是int类型switch operate {case "+"://当operate是+的时候,返回add方法return addcase "-"://当operate是-的时候,返回sub方法return subdefault:return nil}
}func main() {f := test("-")res := f(1, 2)fmt.Printf("res: %v\n", res)
}匿名函数
前面提到了在函数中是不允许嵌套函数的,但是我们可以使用匿名函数,来实现一些简单的功能:
package mainimport "fmt"func main() {//匿名函数和普通函数的区别其实就是没有了函数的名字,当在一个函数中不写函数名的时候就是匿名函数max := func(a int, b int) int {if a > b {return a} else {return b}}(1, 2) //直接在最后面加上()以及实参的时候,就是自己调用自己//r := max(3, 8) //fmt.Printf("r: %v\n", r)fmt.Printf("max: %v\n", max)
}Golang闭包
闭包可以理解成定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁,或者是说函数和其引用环境的组合体
闭包指的是一个函数和与其相关的应用环境组合而成的实体。简单来说,闭包=函数+引用环境。看下面的例子:
package mainimport "fmt"//定义一个函数名为test,该函数返回值是一个函数,这个函数有一个int类型的参数 并且他返回值是一个int类型的数
func test() func(int) int {var x intreturn func(i int) int {x += ireturn x}
}
func main() {f := test()//f赋值为test的返回值,就是返回的函数,初始x为0fmt.Printf("f(10): %v\n", f(10)) //计算0+10=>10 这里x就变成了10 而不是0fmt.Printf("f(20): %v\n", f(20)) //计算10+20=>30 这里x就变成了30 而不是10fmt.Printf("f(30): %v\n", f(30)) //计算30+30=>60 这里x就变成了60 而不是30
}变量f是一个函数并且他引用了其外部作用域中的x变量,此时f就是一个闭包。在f的生命周期内,变量x也一直有效;
package mainimport ("fmt""strings"
)func makeSuffixFunc(suffic string) func(string) string {return func(name string) string {//这里的strings.HasSuff(name.suffic)表示判断name是否以suffic结尾//如果是返回true,否则false 需要导包stringsif !strings.HasSuffix(name, suffic) {return name + suffic} else {return name}}
}
func main() {f := makeSuffixFunc("World")str := f("Hello")fmt.Printf("str: %v\n", str)
}package mainimport "fmt"func cal(base int) (func(int) int, func(int) int) {add := func(a int) int {base += areturn base}sub := func(a int) int {base -= areturn base}return add, sub
}
func main() {add, sub := cal(10)res := add(10)fmt.Printf("res: %v\n", res)res = sub(5)fmt.Printf("res: %v\n", res)
}定义了cal函数,cal函数存在一个形参base,cal函数返回值存在两个,并且这两个都是函数,之后在cal函数中定义两个匿名的函数分别赋值给add 和 sub,最终cal函数返回这两个匿名函数,之后在main函数中,令add sub为cal(10) ,其中base就是10 之后执行res=add(10),而这个10是匿名函数的形参a=10,执行base+=a故base=20
base的值会存储下来,之后res = sub(5),此时sub函数中的形参a就是5,再次执行base-=a,故得到base=15
Go语言中的递归函数
函数内部调用函数自身的函数称之为递归函数
使用递归函数最重要的三点:
递归就是自己调用自己
必须先定义函数的退出条件,没有退出条件,递归将成为死循环
go语言递归函数很可能会产生一大堆的goroutine,也很可能会出现占空间内存溢出的问题
package mainimport "fmt"//数的阶乘
func fc(n int) int {if n <= 1 {return 1} else {res := n * fc(n-1)return res}
}
func main() {res := fc(5)fmt.Printf("res: %v\n", res)
}package mainimport "fmt"
//f(n)=f(n-1)+f(n-2) f(2)==f(1)==1
func fb(n int) int {if n <= 2 {return 1} else {res := fb(n-1) + fb(n-2)return res}
}
func main() {fmt.Printf("fb(3): %v\n", fb(3))
}Go语言中的defer语句
go语言中的defer语句会将其后面跟随的语句进行延时处理,在defer归属的函数即将返回时,姜堰市处理的语句按defer定义的逆序进行执行;也就是说先被defer的语句最后被执行,最后被defer的语句,最先被执行
package mainimport "fmt"func main() {fmt.Printf("start...\n")defer fmt.Printf("stop1...\n")defer fmt.Printf("stop2...\n")defer fmt.Printf("stop3...\n")fmt.Printf("END...\n")
}输出结果如下:

Go语言中的init函数
golang有一个特殊的函数init函数,先于main函数的执行,主要实现包级别的一些初始化操作
init函数额主要特点
init函数先于main函数自动执行,不能被其他函数调用
init函数没有输入参数、返回值
每个包可以有多个init函数
包的每个源文件也可以有多个init函数,这点比较特殊
同一个包的init执行顺序,golang没有明确的定义;
不同包的init函数按照包导入的依赖关系决定执行顺序
初始化顺序:变量初始化>init()>main()
package mainimport "fmt"var i int = initVar()func initVar() int {fmt.Printf("initvar...\n")return 100
}
func init() {fmt.Printf("init2...\n")
}
func init() {fmt.Printf("init...\n")
}
func main() {fmt.Printf("start...\n")
}输出结果为:

同时存在多个init()的时候,遵循自上而下的执行顺序
相关文章:
Golang学习Day2
Go语言中的函数go语言中函数特性go语言有三种函数:普通函数、匿名函数(没有名称的函数)方法(定义在struct上的函数)。receivergo语言中不运算函数重载(overload),也就是说不允许函数…...
Android 中malloc_debug 原理详解
版本基于:Android R 0. 前言 最近上项目中遇到一个native 可能内存泄漏的问题,曾考虑使用HWASAN,但这个工具是针对整个系统,运行代价还是很高的。而笔者遇到的问题大致有所方向,能指定到某一个进程,针对单…...
D. Triangle Coloring【组合数学,乘法逆元】
链接 分析 题目要求我们去求出最优的染色的方法数。首先什么时候是最优的,这里只有两种颜色,不可能取到三条边,即蓝色为B,红色为R,有BBB,RRR,BBR,RRB四种组合,显然最多的就是取两条边,我们想取到…...
【读论文】AttentionFGAN
【读论文】AttentionFGAN介绍网络架构提取红外图像目标信息的网络辨别器损失函数生成器损失函数辨别器损失函数总结参考论文: https://ieeexplore.ieee.org/document/9103116/如有侵权请联系博主介绍 好久没有读过使用GAN来实现图像融合的论文了,正好看…...
ClickHouse 配置文件使用说明
本文主要介绍 ClickHouse 的配置文件。在 ClickHouse 中配置主要分为两类,一类是负责 server 端配置的,另一类是负责用户端配置的。负责 server 端配置的一般会放在 config.xml 文件中,负责用户端配置的一般会放在 users.xml 文件中。当然如果…...
如果不是互联网人,谁会找到这些神器?
一、上线啦 你肯定该问了,这个是什么鬼东西。它本来是一个创建自己网站的网站。 现在使用它可以创建自己的小程序,又不是有点小厉害了。 而且功能强大,还支持微信支付,分销,优惠券,营销等多种功能。 还有多…...
Neo4j优化
使用参数 查询参数 :params设置参数 :param actorName: Tom Hanks参数的冒号后要用空格使用参数用 $ MATCH (p:Person)-[:ACTED_IN]->(m:Movie) WHERE p.name $actorName RETURN m.released AS releaseDate,m.title AS title ORDER BY m.released DESC多个参数 MATCH (p:Pe…...
CF1692G 2^Sort 题解
CF1692G 2^Sort 题解题目链接字面描述题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1提示思路代码实现题目 链接 https://www.luogu.com.cn/problem/CF1692G 字面描述 题面翻译 给你一个长度为 n(∑n<2⋅105)n \ (\sum n < 2\cdot 10^5)n (∑n<…...
关于物理像素,逻辑像素,像素比
关于物理像素、逻辑像素(css像素)、分辨率、像素比的超详细讲解 在日常生活中,有这样一个问题。同样的图片为什么在不同的设备上显示的大小是不一样的。🤒带着这个问题来说明一下。 一、物理像素 设备刚生产出来就已经固定了&a…...
JavaSE基础部分总结
JavaSe基础部分 文章目录JavaSe基础部分1.命名规范2.基本的数据类型3.方法3.1方法的基本格式3.2 方法的分类3.3 方法的注释4.数组4.1 数组的命名格式4.2 数组中存在的址交换的操作4.3数组Arrays常用的方法1. Arrays.asList(数组作为参数或者数据作为参数):2.Arrays.…...
C++基础知识
目录类和对象C static_cast、dynamic_cast、const_cast和reinterpret_cast1、为什么要引入这四种类型转化?2、应用场景。C/C类型转换的本质struct和class的区别为什么会诞生面向对象的编程思想析构函数的执行时机初始化 const 成员变量C const对象(常对象…...
2023/2/24 图数据库Neo4j的理解与应用
1 什么是图数据库(graph database) 十大应用案例:https://go.neo4j.com/rs/710-RRC-335/images/Neo4j-Top-Use-Cases-ZH.pdf “大数据”每年都在增长,但如今的企业领导者不仅需要管理更大规模的数据,还迫切需要从现有…...
适合视力障碍者的Linux
导读有哪些最适合视障用户的 Linux 发行版?让我们一起来看看。 如果有人视力障碍或失明,他们可能会依赖声音提示或其他交互方式(如盲文)来阅读和交流。 他们怎样才能使用 Linux 发行版? 嗯,一般来说&…...
Tina Linux 存储开发指南
Tina Linux 存储开发指南 1 概述 1.1 编写目的 介绍TinaLinux Flash,分区,文件系统等存储相关信息,指导方案的开发定制。 1.2 适用范围 Tina V3.0 及其后续版本。 1.3 相关人员 适用于TinaLinux 平台的客户及相关技术人员。 2 分区管…...
【洛谷 P2670】[NOIP2015 普及组] 扫雷游戏 题解(模拟)
[NOIP2015 普及组] 扫雷游戏 题目背景 NOIP2015 普及组 T2 题目描述 扫雷游戏是一款十分经典的单机小游戏。在 nnn 行 mmm 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻…...
【nohup引发磁盘读写高】nohup命令导致服务器磁盘读写占满该如何修复?
【写在前面】自己在跑一个项目的时候,猛然发现服务器挂了,直接访问不了,呈现出一种卡死现象,我当时都懵了,难道阿里在后端升级,也不会选择在工作日的时间升级吧,于是乎就咨询了一下客服。才有下…...
MySQL(二)索引和SQL优化
MySQL进阶MySQL体系结构存储引擎存储引擎特点InnoDB逻辑存储结构MyISAMMemory存储引擎选择索引索引结构二叉树B-TreeBTreeHash索引分类索引语法SQL性能分析工具SQL执行频率慢查询日志profile详情explain索引使用联合索引索引失效情况SQL提示覆盖索引前缀索引单列索引与联合索引…...
Java常用日期类(包含三代)_Date类及Calendar类等
一.java.util.Date类概述从JDK 1.0出现。表示一个日期和时间,精确到毫秒,内部getTime()从1970年1月1号开始算。1. java.util.Date类构造部份构造已经过时,重点看以下两个构造。public Date()从运行程序的此时此刻到时间原点经历的毫秒值&…...
计算机网络你都懂了吗
文章目录一、计算机网络的定义简单定义通用定义二、计算机网络通信过程三、什么是网络协议(Protocol)四、网络协议组成及功能一、计算机网络的定义 简单定义 计算机网络是一些相互连接的、自治的计算机系统的集合。 通用定义 将处于不同位置并具有独…...
3.4 Spring Boot 日志配置
第3章 Spring Boot 的系统配置 3.1 Spring Boot 系统配置文件 3.2 Spring Boot 自定义配置项 3.3 Spring Boot 其他配置 3.4 Spring Boot 日志配置 3.5 实战:Spring Boot 实现系统多环境配置 3.4 Spring Boot 日志配置 日志对于系统监控、故障定位非常重要…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
