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

简介: 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语言函数灵活,操作也较为方便。

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
2月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
223 1
|
3月前
|
存储 Java Go
对比Java学习Go——函数、集合和OOP
Go语言的函数支持声明与调用,具备多返回值、命名返回值等特性,结合`func`关键字与类型后置语法,使函数定义简洁直观。函数可作为一等公民传递、赋值或作为参数,支持匿名函数与闭包。Go通过组合与接口实现面向对象编程,结构体定义数据,方法定义行为,接口实现多态,体现了Go语言的简洁与高效设计。
|
4月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
312 1
|
4月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
408 0
|
4月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
268 0
|
4月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
250 0
|
4月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
348 0
|
4月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
4月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
存储 设计模式 Cloud Native
云原生系列Go语言篇-类型、方法和接口 Part 1
通过前面章节的学习,我们知道Go是一种静态类型语言,包含有内置类型和用户定义类型。和大部分现代编程语言一样,Go允许我们对类型关联方法。它也具备类型抽象,可以编写没有显式实现的方法。
186 0