盘点Go语言中那些酷酷的语法

简介: 盘点Go语言中那些酷酷的语法

虽然写Go语言已经一年有余,认识Go语言已经近三年,但是写Go代码的快乐并未随着时间的推移而逐渐消沉,有时仍然会因为写一段伶俐的代码而感到很酷,所以想专门写一篇基础性的文章,来记录一下Go语言中那些很酷的语法,非常适合Go语言的新手同学哦!😆

列个大纲先看下具体有哪些吧:

  • 😗少即是多:简短变量声明和函数返回值屏蔽
  • 😉追逐lambda:什么是匿名函数和闭包
  • 😀defer语法:将函数放在栈中延迟执行
  • 😏go关键字:嗖!的一下go出一个协程
  • 😁Format函数:日期格式化的有趣约定
  • 😬错误处理:没有try…catch…一样可以游刃有余
  • 😯使用通信的方式来共享内存:高效的channel

以下是正文:

少即是多:简短变量声明和函数返回值屏蔽

知道Go语言是有多么简洁了吧:

func add(i int) (int, error) {
   return i + 1, nil
}
func TestLessIsMore(t *testing.T) {
   //声明变量i
   i := 10
   
   j, _ := add(i) //屏蔽err返回值
   fmt.Println(j)
   
   _, _ = add(i) //屏蔽全部返回值
}

追逐lambda:什么是匿名函数和闭包

匿名函数、闭包和lambda三者是完全不同的三个概念,但是又有着相互的关联。

首先是匿名函数,它是指在代码中定义的没有名字的函数。匿名函数可以被赋值给变量,也可以作为参数传递给其他函数。

闭包是指一个函数内部引用了外部函数的变量,并且可以在函数外部被调用或访问时,依然能够保持对这些变量的访问能力。换句话说,闭包是一个函数以及其引用的外部变量的组合体。

在Go语言中,闭包的实现非常简洁。当一个函数内部定义了一个匿名函数,并且这个匿名函数引用了外部函数的变量时,Go语言会自动将这些变量捕获到闭包中。通过闭包,我们可以在函数外部对这些变量进行访问、修改等操作,即使外部函数已经执行完毕,这些变量的值也会被保留。

lambda表达式是一种函数式编程的概念,它是一种匿名函数的简洁语法表示。在一些编程语言中,如Python、JavaScript等,lambda表达式可以用一种紧凑的方式定义一个匿名函数。通常情况下,lambda表达式用于编写简单的、单行的函数逻辑。

虽然匿名函数和lambda表达式有相似之处,都是指没有名称的函数,但是它们的使用场景和语法细节可能会有所不同。在Go语言中,匿名函数的定义比较灵活,可以包含多行代码,有更多的语法支持;而lambda表达式通常用于简单的、单行的函数逻辑。另外,Go语言中没有直接对应于lambda表达式的语法,但可以通过匿名函数来实现类似的功能。

匿名函数和lambda:

type operation func(int, int) int
func calculate(a, b int, op operation) int {
  return op(a, b)
}
func TestFun(t *testing.T) {
  //匿名函数
  f := func(i, j int) int {
    return j + i
  }
  f(1, 1)
  // lambda函数示例
  add := func(a, b int) int {
    return a + b
  }
  subtract := func(a, b int) int {
    return a - b
  }
  result1 := calculate(5, 3, add)
  fmt.Println(result1) // 输出:8
  result2 := calculate(5, 3, subtract)
  fmt.Println(result2) // 输出:2
}

Go实现闭包:

func TestBiBao(t *testing.T) {
   // 外部函数
   outer := func() {
      // 外部变量
      count := 0
      // 内部函数(闭包)
      inner := func() {
         count++
         fmt.Println(count)
      }
      // 调用内部函数
      inner()
   }
   // 调用外部函数
   outer() // 输出:1
   outer() // 输出:1
}

在上面的代码中,我们定义了一个外部函数outer,它内部定义了一个匿名函数innerinner引用了外部函数outer的变量count。每次调用outer函数时,都会创建一个新的闭包,这个闭包包含了独立的count变量。

在调用outer函数时,内部函数inner会被调用,并对count变量进行递增操作,并输出结果。由于闭包捕获了外部变量,所以每次调用内部函数时,都能正确地访问和修改之前的count值。

需要注意的是,在每次调用outer函数时,都会创建一个新的闭包,因此每次调用时的count变量都是独立的。这就是闭包的特性之一,它可以在函数调用之间保持状态。

闭包在一些场景下非常有用,例如:

  1. 保存状态:通过闭包,可以在函数调用之间保持某些状态。每次调用闭包函数时,可以继续使用之前的状态,而不需要将状态传递给函数的参数。
  2. 实现私有变量:通过在闭包内定义的变量,可以实现一种私有化的效果,外部无法直接访问或修改这些变量,只能通过闭包函数提供的接口进行操作。
  3. 回调函数:可以将匿名函数作为参数传递给其他函数,并在需要时进行调用。通过闭包,可以将上下文信息传递给回调函数,实现更灵活的函数调用。

需要注意的是,闭包引用的外部变量在闭包函数内部可能会被修改,因此在使用闭包时需要注意变量的生命周期和可变性。

defer语法:将函数放在栈中延迟执行

go defer 是 Go 语言中的语句,它用于在函数返回之前执行一些代码。使用 defer 语句可以确保在函数执行完毕后,一些必要的清理工作或者收尾工作被执行。

func TestDefer(t *testing.T) {
   defer func() {
      fmt.Println("defer func ...")
   }()
   fmt.Println("no defer ...")
}

go语法:嗖!的一下go出一个协程

Go最厉害的特性之一,可以看下我这篇文章的详解:深入浅出Go并发之协程—goroutine

func TestGoroutine(t *testing.T) {
  group := sync.WaitGroup{}
  group.Add(1)
  go func() {
    fmt.Println("this is go Sou fun ...")
    group.Done()
  }()
  
  group.Wait()
}

Format函数:日期格式化的有趣约定

先看代码,这是Go语言中将日期转换为YYYY-MM-DD HH:MM:SS的函数,当时二话没说就搜了下为什么要这样写,很快就得出了答案,是因为好记😅,在国外一般都是把年份放在最后,所以我们吧年份挪到最后就会发现,可以使用010203040506这样的方式记下来,貌似确实很好记…

func TestTimeFormat(t *testing.T) {
   //12小时制
   format := time.Now().Format("2006-01-02 03:04:05")
   fmt.Println(format)
   //24小时制
   format2 := time.Now().Format("2006-01-02 15:04:05")
   fmt.Println(format2)
}

错误处理:没有try…catch…一样可以游刃有余

Go语言中的异常处理机制可以让我们在程序中捕获和处理错误和异常情况,而不是使用try…catch…这样的异常块来缓存异常。这样的设计可以让我们更灵活地处理错误和异常,并且可以更好地控制程序的流程。

与此同时,使用defer+recover()可以让我们捕获程序中可能发生的异常。

func TestRecover(t *testing.T) {
  f := func() {
    panic("has err ...")
  }
  defer func() {
    if err := recover(); err != nil {
      fmt.Println(err)
    }
  }()
  f()
}

使用通信的方式来共享内存:高效的channel

在Go语言中,通道(channel)是一种用于在goroutine之间进行通信的特殊类型。通道提供了一种方式,可以在goroutine之间传递值,这使得并发编程变得更加简单和有效。

下面是一些使用channel的方式:

  • 并发求和:使用通道可以轻松地实现并发求和。在常规的求和中,所有的计算都在同一个goroutine中执行,而使用通道可以在多个goroutine中并行执行计算。
func sum(n int) int {  
    sum := 0  
    for i := 0; i < n; i++ {  
        sum += i  
    }  
    return sum  
}  
  
func main() {  
    n := 1000000  
    c := make(chan int)  
    for i := 0; i < 10; i++ {  
        go func() {  
            c <- sum(n)  
        }()  
    }  
    for i := 0; i < 10; i++ {  
        sum := <-c  
        fmt.Println(sum)  
    }  
}
  • 并发队列:使用通道可以轻松地实现并发队列。在常规的队列中,所有的操作都在同一个goroutine中执行,而使用通道可以在多个goroutine中并行执行操作。
func main() {  
    c := make(chan int)  
    for i := 0; i < 10; i++ {  
        go func(i int) {  
            c <- i  
        }(i)  
    }  
    for i := 0; i < 10; i++ {  
        fmt.Println(<-c)  
    }  
}

最后

好了,以上就是我总结出的Go语言中那些很酷的语法,当然想要将这些优雅的操作进行灵活的使用并非易事,而且Go语言中也存在其他非常优秀的语法和设计模式,欢迎各位读者在评论区进行分享和讨论。

相关文章
|
4月前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
4月前
|
编译器 Go
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
|
21天前
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
41 10
|
4月前
|
存储 Go
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
100 3
Go 语言入门指南:切片
|
4月前
|
开发框架 前端开发 Go
eino — 基于go语言的大模型应用开发框架(二)
本文介绍了如何使用Eino框架实现一个基本的LLM(大语言模型)应用。Eino中的`ChatModel`接口提供了与不同大模型服务(如OpenAI、Ollama等)交互的统一方式,支持生成完整响应、流式响应和绑定工具等功能。`Generate`方法用于生成完整的模型响应,`Stream`方法以流式方式返回结果,`BindTools`方法为模型绑定工具。此外,还介绍了通过`Option`模式配置模型参数及模板功能,支持基于前端和用户自定义的角色及Prompt。目前主要聚焦于`ChatModel`的`Generate`方法,后续将继续深入学习。
635 7
|
4月前
|
存储 开发框架 Devops
eino — 基于go语言的大模型应用开发框架(一)
Eino 是一个受开源社区优秀LLM应用开发框架(如LangChain和LlamaIndex)启发的Go语言框架,强调简洁性、可扩展性和可靠性。它提供了易于复用的组件、强大的编排框架、简洁明了的API、最佳实践集合及实用的DevOps工具,支持快速构建和部署LLM应用。Eino不仅兼容多种模型库(如OpenAI、Ollama、Ark),还提供详细的官方文档和活跃的社区支持,便于开发者上手使用。
919 8
|
4月前
|
存储 缓存 监控
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
64 3
|
4月前
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
4月前
|
SQL 安全 Java
阿里双十一背后的Go语言实践:百万QPS网关的设计与实现
解析阿里核心网关如何利用Go协程池、RingBuffer、零拷贝技术支撑亿级流量。 重点分享: ① 如何用gRPC拦截器实现熔断限流; ② Sync.Map在高并发读写中的取舍。
148 0
|
4月前
|
存储 算法 安全
基于 Go 语言的公司内网管理软件哈希表算法深度解析与研究
在数字化办公中,公司内网管理软件通过哈希表算法保障信息安全与高效管理。哈希表基于键值对存储和查找,如用户登录验证、设备信息管理和文件权限控制等场景,Go语言实现的哈希表能快速验证用户信息,提升管理效率,确保网络稳定运行。
64 0