三分钟学Go语言——函数深度解析(上)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 三分钟学Go语言——函数深度解析(上)

基本原理


函数,几乎是每种编程语言的必备语法,通过函数把一系列的动作汇总起来,在不同的地方重复使用。


我们在数学中曾经就使用过函数,他的形式类似于y=f(x),这就是一个完整的调用过程,y就是函数计算后得到的值,x就是传入的变量。


怎么用?


相信在看这个教程的人肯定已经接触过其他的编程语言,我就不多废话了,就是干。


aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzIwMjAtMDQtMjUtMTUyMzI1LmpwZw.png


go语言中最基本的函数是这样的,以func为关键字标记函数


func functionParam(num int) {
}


当然了,可以有多个形参,类型相同时可以省略,如下


//多个参数的函数
func functionParams(a, b int, c string) {
}



上面说过的函数都没有返回值,一般的函数都有返回值,没有返回值的函数要么是引用传递,可以直接改变参数内容,要么就是用于单元测试或者打印输出等。

aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzIwMjAtMDQtMjUtMTUxMDEyLmpwZw.png


没有返回值的函数就像一个不完整的男人,只能接受不能输出,来看看这个男人有一个输出的情况。


返回值标记在函数第一个括号后面,由于go语言是强类型语言,但又和python不同,要写出返回值类型。

//一个返回值
func funcReturnOne() int {
  return 1
}

如果说是有多个返回值,要用打括号括起来。

//多个返回值
func funReturnMany() (int, int) {
  return 1, 2
}



上面的返回值全部都是匿名的,可以赐他一个名字,函数中不用定义返回值,可以省略几行代码。


//返回值有名称
func funReturnName() (res int) {
  //var res  int  省掉了
  res = 1 + 1
  return
}


用返回就有接收,函数外部用这种方式接收

//接收多个返回值
  a, b := funReturnMany()



值传递,引用传递


刚刚有说到函数没有返回值的时候,要么是只需要打印结果,要么是只做单元测试,除了这两种情况,没有返回值的函数就是做了很多事情的你没有和老板汇报一样,没有任何意义!


引用传递和c++类似,先举个值传递的例子。

//值传递
func noChange(a, b int) {
  tmp := a
  a = b
  b = tmp
}

调用打印结果看看


a, b := 1, 2
  fmt.Printf("原值 a:%v,b:%v \n", a, b)
  noChange(a, b)
  //值传递,并没有修改原值
  fmt.Printf("值传递后 a:%v,b:%v \n", a, b)


看!像不像任劳任怨的你,忙活半天被老板喜欢的小张抢了功劳。


原值 a:1,b:2 
值传递后 a:1,b:2


下面来看看引用传递的例子。在类型前加一个星号代表该参数是一个指针


// 引用传递,参数加*号代表指针
func change(a,b *int){
  tmp := *a
  *a = *b
  *b = tmp
}


学过c++再来学go简直是如虎添翼,c++中有一个指针的概念go语言里也有。

//引用传递,&就是c中的取地址
  change(&a,&b)
  fmt.Printf("引用传递后 a:%v,b:%v \n", a, b)


输出结果,可以看到值被调换了。引用传递需要加&符号,术语叫取地址。函数里的对他做的任何操作都会改变原来的变量内容。

引用传递后 a:2,b:1


上面的例子传入的是指针,还有一种叫引用类型,和指针的区别是不需要星号和&,对他的修改会直接改动到原有变量的值。


ps:go语言中只有三种引用类型,slice(切片)、map(字典)、channel(管道)


函数进阶


上面说的东西都很简单了,基本学过任何一门语言的人都能瞬间看懂,和pythonc++javascript一样,go中也有把函数打作参数传递的语法。

像这样,functionValue函数的形参里有一个名为do的函数,需要提前指定do函数有什么参数和返回值。


func functionValue(a, b int, do func(int, int) int) {
  fmt.Println(do(a, b))
}

然后do(a,b)是在functionValue内部调用的。这种特性有什么用呢?定义两个参数为int,返回为int的函数。

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

因为规则符合do函数的规则,两个都可以传递过去,看!这就不用修改函数内部而出现了两种效果。

functionValue(1, 1, add)
  functionValue(1, 1, sub)


在设计模式里,这种方式叫装饰器模式(Decorator Pattern):允许向一个现有的对象添加新的功能,同时又不改变其结构。


aHR0cHM6Ly9jb2RpbmczbWluLm9zcy1hY2NlbGVyYXRlLmFsaXl1bmNzLmNvbS9jb2RpbmczbWluLzIwMjAtMDQtMjUtMTU1MzUxLmpwZw.png


当然,你也不必每次传递函数的时候都憨厚老实的定义一个新函数,因为有时候你定义的函数就只会在这里用到,只不过是把实现放在调用外部,而不修改原函数代码罢了。


  //匿名函数
  functionValue(1, 1, func(i1 int, i2 int) int {
    return i1 * i2
  })

上面这个例子多看几遍啊!!

实际的使用

你可以参考函数测速例子

定义一个测速函数。


func speedTime(handler func() (string), funcName string) {
  t := time.Now()
  handler()
  elapsed := time.Since(t)
  fmt.Println(funcName+"spend time:", elapsed)
}

传入不同的函数都可以测速度。


speedTime(appendStr, "appendStr")
speedTime(appendStrQuick, "appendStrQuick")



Tips


  • 还有你可以传filter函数做过滤,mapping做映射等实际的用法
  • 有时候也可以作为排序递增,递减的依据


b站


今天小熊在b站直播写文章了,虽然只有9个人在看,但是还有打赏,很开心!!!

12点了,终于写完了 ,晚安各位。


image.png



我的b站直播链接:https://live.bilibili.com/22043742

相关文章
|
5天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
23 2
|
3天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
11 2
|
3天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
14 2
|
7天前
|
程序员 Go
go语言中的控制结构
【11月更文挑战第3天】
84 58
|
6天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
3天前
|
Go
go语言中的 跳转语句
【11月更文挑战第4天】
10 4
|
3天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
14 1
|
7天前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
7天前
|
Go 数据处理 调度
探索Go语言的并发模型:Goroutines与Channels的协同工作
在现代编程语言中,Go语言以其独特的并发模型脱颖而出。本文将深入探讨Go语言中的Goroutines和Channels,这两种机制如何协同工作以实现高效的并发处理。我们将通过实际代码示例,展示如何在Go程序中创建和管理Goroutines,以及如何使用Channels进行Goroutines之间的通信。此外,本文还将讨论在使用这些并发工具时可能遇到的常见问题及其解决方案,旨在为Go语言开发者提供一个全面的并发编程指南。
|
5天前
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。

推荐镜像

更多