go语言函数、方法、闭包(详解)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: go语言函数、方法、闭包(详解)

文章目录


前言


函数在数学中为两集合间的一种对应关系:输入值集合中的每项元素都能对应唯一一项输出值集合中的元素


在编程语言中函数为一类操作的集合体,具有一定的功能,有函数名、输入(参数)、输出(返回值)


一、什么是Go语言函数?


Go语言中支持多参数、多返回值


1.Go语言函数都包含什么?


函数声明


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


函数参数


  值传递
  引用传递 
  函数可以作为另一个函数的实参进行回调


函数闭包(用于函数式编程,匿名函数)


  go编译器会对其进行识别,将闭包的变量存放在堆空间内
  并且闭包时不是返回了一个匿名函数,而是返回了一个结构体
  记录下函数返回地址和引用的环境中的变量地址
  同一个函数进行闭包,会因为环境变量的不同无法共享变量
  闭包函数内的变量进行改变会影响到当前所处的环境中的变量


函数方法


  函数方法要接收者函数,接收者函数可以是命名类型或者结构体类型的一个值或者一个指针。
  定义格式如下:
      接收者区域
    func(名称 类型)函数名()返回值类型{
      函数体
    }
  注意点:
    函数方法在执行时如果接收者是一个结构体,在函数内修改结构体数据,原结构体不会修改
    (会将结构体变量数据拷贝一份给和函数)
    如果是一个结构体指针,那么可以生效(直接将该结构体给函数)


2.简单的实现一个函数


代码如下(示例):


// 选最大值函数
//函数名
func maxs(a, b int) int {//括号内是参数列表,括号外int是返回值类型
  if a > b {
    return a
  } else {
    return b
  }
}


3.实现函数多参数


这里是在编写日志系统的时候写的一个输出日志的函数


代码如下(示例):


// 日志对象的方法,用于输出日志信息
//这里的args ...interface{}代表可以传任一个不同类型的参数
func (l LogGer) outLog(level logLevel, args ...interface{}) {
  if !l.eqLevel(level) {
    return
  }
  //看哪里调用这个函数了,哪里出错哪里调用,为了记录下出错的文件行号
  _, file, line, ok := runtime.Caller(2)
  file = strings.Split(file, "/")[len(strings.Split(file, "/"))-1]
  if !ok {
    return
  }
  filestr, _ := downloadLevel(level)
  fmt.Printf("[%s] [%s] [文件:%s] [行号:%d] 附加信息:", time.Now().Format("2006-01-02 15:03:04"), filestr, file, line)
  //对传进来的不定个参数进行解析
  for _, v := range args {
    fmt.Print(v)
  }
  fmt.Printf("\n")
}


4.实现函数多返回值


这里是在编写日志系统的时候写的一个输出日志的函数


代码如下(示例):


//返回int类型与错误类型
func judgeName(name string) (int, error) {
  if name=="jack"{
    return 0,nil
  }
  return -1, errors.New("传进来的不是jack")
}


二、什么是Go语言方法?


方法与函数有一定的区别,接口的话有所属的结构体作为接受者,相应的对象可以调用该方法,函数只实现了一定的功能,不能使用对象直接调用。


1.简单实现一个方法


代码如下(示例):


// 定义一个结构体并添加方法
type user struct {
  name        string
  age         int
  speak_array string
}
//属于结构体的方法
//这里的(Someone user)Someone是接受者名,user是类型还可以是user指针类型
func (Someone user) speak() {
  fmt.Printf("%s说:我今年%d岁,%s\n", Someone.name, Someone.age, Someone.speak_array)
}


二、什么是函数闭包?


func getSuperS() {
  //创建一个函数变量数组
  var temp [3]func() int
  j := 0
  for i := 0; i < 3; i++ {
    //直接使用当前所处环境中的j
    temp[i] = func() int {
      j++
      return j
    }
  }
  /*
    函数闭包使用的是该匿名函数所处环境的变量,如果变量重新声明
    就导致匿名函数使用的变量不同,结果也就是不再共享一个变量
    j定义在for外部,每次生成匿名函数使用的都是使用的同一个j
    (在for循环内部改变j的值不会影响该性质)
    j定义在for循环内部,每一次循环将产生一个新的j变量,三个匿名函数使用的也就不是同一个j了
  */
  fmt.Println(temp[0](), temp[0](), temp[0]())
  fmt.Println(temp[1](), temp[1](), temp[1]())
  fmt.Println(temp[2](), temp[2](), temp[2]())
}


总结


Go语言是一门面向过程编程语言,但是合理的使用函数也可以达到与面向对象编程语言类似的结果,Go语言函数灵活,操作也较为方便。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1天前
|
安全 Java Go
探索Go语言在高并发环境中的优势
在当今的技术环境中,高并发处理能力成为评估编程语言性能的关键因素之一。Go语言(Golang),作为Google开发的一种编程语言,以其独特的并发处理模型和高效的性能赢得了广泛关注。本文将深入探讨Go语言在高并发环境中的优势,尤其是其goroutine和channel机制如何简化并发编程,提升系统的响应速度和稳定性。通过具体的案例分析和性能对比,本文揭示了Go语言在实际应用中的高效性,并为开发者在选择合适技术栈时提供参考。
|
4天前
|
存储 Ubuntu Go
在Ubuntu 16.04上安装Go 1.6的方法
在Ubuntu 16.04上安装Go 1.6的方法
11 1
|
4天前
|
存储 Ubuntu Go
在Ubuntu 18.04上安装Go的方法
在Ubuntu 18.04上安装Go的方法
8 1
|
4天前
|
存储 Ubuntu Linux
在Ubuntu 14.04上安装Go 1.6的方法
在Ubuntu 14.04上安装Go 1.6的方法
12 1
|
5天前
|
运维 Kubernetes Go
"解锁K8s二开新姿势!client-go:你不可不知的Go语言神器,让Kubernetes集群管理如虎添翼,秒变运维大神!"
【8月更文挑战第14天】随着云原生技术的发展,Kubernetes (K8s) 成为容器编排的首选。client-go作为K8s的官方Go语言客户端库,通过封装RESTful API,使开发者能便捷地管理集群资源,如Pods和服务。本文介绍client-go基本概念、使用方法及自定义操作。涵盖ClientSet、DynamicClient等客户端实现,以及lister、informer等组件,通过示例展示如何列出集群中的所有Pods。client-go的强大功能助力高效开发和运维。
24 1
|
6天前
|
SQL 关系型数据库 MySQL
Go语言中使用 sqlx 来操作 MySQL
Go语言因其高效的性能和简洁的语法而受到开发者们的欢迎。在开发过程中,数据库操作不可或缺。虽然Go的标准库提供了`database/sql`包支持数据库操作,但使用起来稍显复杂。为此,`sqlx`应运而生,作为`database/sql`的扩展库,它简化了许多常见的数据库任务。本文介绍如何使用`sqlx`包操作MySQL数据库,包括安装所需的包、连接数据库、创建表、插入/查询/更新/删除数据等操作,并展示了如何利用命名参数来进一步简化代码。通过`sqlx`,开发者可以更加高效且简洁地完成数据库交互任务。
13 1
|
5天前
|
算法 NoSQL 中间件
go语言后端开发学习(六) ——基于雪花算法生成用户ID
本文介绍了分布式ID生成中的Snowflake(雪花)算法。为解决用户ID安全性与唯一性问题,Snowflake算法生成的ID具备全局唯一性、递增性、高可用性和高性能性等特点。64位ID由符号位(固定为0)、41位时间戳、10位标识位(含数据中心与机器ID)及12位序列号组成。面对ID重复风险,可通过预分配、动态或统一分配标识位解决。Go语言实现示例展示了如何使用第三方包`sonyflake`生成ID,确保不同节点产生的ID始终唯一。
go语言后端开发学习(六) ——基于雪花算法生成用户ID
|
7天前
|
JSON 缓存 监控
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
Viper 是一个强大的 Go 语言配置管理库,适用于各类应用,包括 Twelve-Factor Apps。相比仅支持 `.ini` 格式的 `go-ini`,Viper 支持更多配置格式如 JSON、TOML、YAML
go语言后端开发学习(五)——如何在项目中使用Viper来配置环境
|
3天前
|
NoSQL Go Redis
Go语言中如何扫描Redis中大量的key
在Redis中,遍历大量键时直接使用`KEYS`命令会导致性能瓶颈,因为它会一次性返回所有匹配的键,可能阻塞Redis并影响服务稳定性。为解决此问题,Redis提供了`SCAN`命令来分批迭代键,避免一次性加载过多数据。本文通过两个Go语言示例演示如何使用`SCAN`命令:第一个示例展示了基本的手动迭代方式;第二个示例则利用`Iterator`简化迭代过程。这两种方法均有效地避免了`KEYS`命令的性能问题,并提高了遍历Redis键的效率。
11 0
|
4天前
|
监控 Serverless Go
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决
Golang 开发函数计算问题之Go 语言中切片扩容时需要拷贝原数组中的数据如何解决