Go语言中的函数:简单有趣的代码块魔法(五)

news2024/10/22 12:49:07

Go语言中的函数:简单有趣的代码块魔法

在这里插入图片描述

Go语言中的函数不仅简单易用,还带有一些有趣的小魔法,让它在代码世界里游刃有余。本文将带你通俗易懂地理解Go函数的声明与调用、多返回值、命名返回值、可变参数、匿名函数与闭包,以及函数作为参数和返回值的高级玩法。我们不仅会解释这些概念,还会在其中融入一些实战经验和小幽默,让你在学习的路上轻松自如。

1. 函数声明与调用

函数是代码的基本构建块,它可以重复使用并提高代码的可维护性。Go语言中的函数声明简单而直接。让我们从最基本的函数声明开始:

package main

import "fmt"

// sayHello 是一个简单的函数,它接受一个字符串并输出一条问候语。
func sayHello(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

func main() {
    sayHello("Go") // 调用函数
}
小提示:
  • func 是声明函数的关键词,后面跟着函数名、参数列表和函数体。
  • 如果你有过其他编程语言的经验,可能会注意到:没有括号包裹参数类型,Go让事情简单直白。

2. 多返回值函数

Go语言给了我们一种超级能力:一个函数可以返回多个值!这在错误处理、复杂逻辑返回等场景中非常有用。比如,你可以让一个函数同时返回计算结果和错误信息。

来看看我们常见的多返回值函数:

package main

import (
    "errors"
    "fmt"
)

// divide 函数返回两个数的商和可能的错误
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("除数不能为0")
    }
    return a / b, nil
}

func main() {
    result, err := divide(10, 2)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }
}
实战经验:
  • 多返回值常用于返回操作结果和错误处理,这使得我们不需要额外创建一个复杂的结构体去返回多个信息。
  • 记得检查第二个返回值是否为 nil,这能帮你避免很多潜在的Bug和程序崩溃。

3. 命名返回值

有时候,Go函数的返回值可以带上名字,这不仅让代码更具可读性,还可以省去 return 语句中显示返回的变量。来看个例子:

package main

import "fmt"

// add 函数的返回值被命名为 result
func add(a, b int) (result int) {
    result = a + b // 直接给 result 赋值
    return         // 不用显式写 return result
}

func main() {
    fmt.Println(add(3, 4)) // 输出: 7
}
开发经验分享:
  • 命名返回值 常用于短小的函数,尤其当函数的意图十分清晰时,它能让代码显得更干净。
  • 但要注意,命名返回值可能会让新手感到困惑,不要滥用。如果函数体太复杂,建议依然使用显式返回值。

4. 可变参数函数

你知道Go语言允许你传递可变数量的参数给一个函数吗?这就像个超级购物袋,你可以随便往里面塞东西。无论你是想传递1个、2个还是10个参数,Go都可以轻松处理。

package main

import "fmt"

// sum 函数接收可变数量的 int 参数
func sum(nums ...int) int {
    total := 0
    for _, num := range nums {
        total += num
    }
    return total
}

func main() {
    fmt.Println(sum(1, 2, 3))       // 输出: 6
    fmt.Println(sum(10, 20, 30, 40)) // 输出: 100
}
开发技巧:
  • 可变参数函数的典型场景包括日志记录、计算不定数量的输入等。
  • 你也可以将已有的切片(slice)传递给可变参数函数,前面加个 ... 即可。
nums := []int{1, 2, 3}
sum(nums...)  // 传入切片

5. 匿名函数与闭包

匿名函数就是没有名字的函数,用完即扔,非常方便。而闭包(closure)是更有趣的概念,它让函数捕获外部变量,并记住它们的状态。让我们来看看这些魔法是如何施展的。

匿名函数
package main

import "fmt"

func main() {
    // 定义并立即调用匿名函数
    func() {
        fmt.Println("我是匿名函数!")
    }()
}
闭包:创建一个可以记住状态的函数
package main

import "fmt"

// fibonacci 返回一个生成斐波那契数列的闭包
func fibonacci() func() int {
    a, b := 0, 1
    return func() int {
        result := a
        a, b = b, a+b
        return result
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}
闭包开发经验:
  • 闭包常用于需要保存某些状态或上下文的场景,比如:生成器(如上面的 Fibonacci 数列)、记忆化(缓存函数结果),或者封装一些业务逻辑。
  • 小心使用闭包中的变量捕获,因为这些变量是共享的,在并发场景下可能需要同步处理。

6. 函数作为参数和返回值

Go的函数是“一等公民”,这意味着你可以像处理普通变量一样处理函数,可以将函数作为参数传递,也可以将它作为返回值。

函数作为参数
package main

import "fmt"

// 高阶函数 apply 接受一个函数作为参数,并对值进行操作
func apply(fn func(int, int) int, a, b int) int {
    return fn(a, b)
}

func main() {
    sum := func(a, b int) int { return a + b }
    result := apply(sum, 10, 20)
    fmt.Println(result) // 输出: 30
}
函数作为返回值
package main

import "fmt"

// makeAdder 返回一个闭包函数,它会累加给定的值
func makeAdder(x int) func(int) int {
    return func(y int) int {
        return x + y
    }
}

func main() {
    addFive := makeAdder(5)
    fmt.Println(addFive(10)) // 输出: 15
}
实战经验:
  • 高阶函数(函数作为参数或返回值)在Go语言的简洁函数式编程中非常实用,常用于编写通用性强的代码,比如处理器链、回调函数等。
  • 这种函数式编程风格,虽然在Go中不是核心,但灵活运用能提升代码的优雅性和可复用性。

扩展阅读:

  • Go语言官方网站
  • Effective Go - 学习更优雅的Go代码编写方式
  • A Tour of Go - 交互式学习Go

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2213280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mac地址漂移实验

MAC地址漂移是指交换机的MAC地址表中的内容被改变&#xff0c;导致网络中的数据包无法正确传输到目标设备。在正常情况下&#xff0c;网络中的MAC地址应该是稳定的&#xff0c;不会频繁发生变化。因此&#xff0c;如果在短时间内出现大量MAC地址漂移的情况&#xff0c;可能意味…

【Web——HTML 初阶】网页设计标题

♥HTML&#xff08;HyperText Markup Language&#xff0c;超文本标记语言&#xff09;是构建网页和Web应用的基础语言之一。它不是一种编程语言&#xff0c;而是一种标记语言&#xff0c;用于描述网页的结构和内容。HTML使用标签&#xff08;tags&#xff09;来标记不同类型的…

NFTScan | 10.07~10.13 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期&#xff1a;2024.10.07~ 2024.10.13 NFT Hot News ​01/ 数据&#xff1a;9 月份加密市场大多数指标均出现下降&#xff0c;链上总交易量下降 13% 10 月 7 日&#xff0c;据 The Block 研究总监 la…

阿里云ACP好考吗?阿里云ACP备考攻略及工具一站式备齐!

经常有小伙伴问&#xff1a;阿里云ACP好考吗&#xff1f;阿里云ACP难吗&#xff1f;作为过来人&#xff0c;给大家做好了阿里云ACP认证的整体规划&#xff0c;你只需要跟着做就okk啦&#xff01;再告诉大家一个好消息&#xff1a;目前阿里云ACP还是不用做实验的&#xff01; 一…

如何在算家云搭建Video-Infinity(视频生成)

一、模型介绍 Video-Infinity是一个先进的视频生成模型&#xff0c;使用多个 GPU 快速生成长视频&#xff0c;无需额外训练。它能够基于用户提供的文本或图片提示&#xff0c;创造出高质量、多样化的视频内容。 二、模型搭建流程 1.大模型 Video-Infinity 一键使用 基础环境…

深圳出手!新能源汽车被针对了

文 | AUTO芯球 作者 | 雷慢 这个政策好啊&#xff0c;我举双手赞成&#xff01; 来看&#xff0c;深圳刚发布了针对新能源车地下车库充电的管理规范&#xff0c; 我替你们扒了一遍&#xff0c;要点就几个&#xff0c; 新能源充电桩不能设在地下四层及以下&#xff0c; 这点…

产品图册转换为电子图册

​标传统的产品图册不仅体积庞大&#xff0c;携带不便&#xff0c;而且更新换代速度慢&#xff0c;信息更新不及时。在这个信息化时代&#xff0c;我们需要一种更加便捷、高效的方式来展示产品。那么&#xff0c;可翻页的电子画册怎么制作呢&#xff1f; 1.要制作电子杂志,首先…

“全民拼团:解锁社交电商新玩法,乐享购物与分红“

在当前电子商务领域&#xff0c;一种创新的购物体验——全民团购风潮正逐渐兴起。它创造性地将社交功能与电商购物相结合&#xff0c;借助团购、拼购等活动&#xff0c;不仅使消费者能够享受到更优惠的价格&#xff0c;更赋予购物过程一种全新的乐趣和互动性。 全民团购模式的独…

史诗级回归,连播两集,燃到让人窒息

《超人和露易丝》自2021年首播以来&#xff0c;虽然起初没有掀起太大的波澜&#xff0c;但凭借着温情的家庭故事与用心的制作&#xff0c;慢慢积累了口碑。它不再是简单的“英雄拯救世界”套路&#xff0c;而是把超人的身份放进了家庭的框架里&#xff0c;展现了英雄在拯救世界…

模板的路由的配置

1.安装路由 pnpm install vue-router 2.配置相应的路由 routes.ts //对外暴露这些配置的路由(常量路由)export const constantRoutes [{path: /login,name: login,//命名路由 权限用到component: () > import(/views/login/LoginPage.vue)},{path: /,name: layout,compo…

【Java数据结构】---七大排序(插入排序和选择排序)

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 什么是排序&#xff1f; 使一串数据…

新的一轮前端面试已来临,避坑指南来 get!

最近看到很多人都在投简历&#xff0c;可是很多人对待面试不够认真&#xff0c;只会等待结果&#xff0c;不去努力。所以整理一些懒人面试技巧给大家。 我们说说目前应用面积最广的 Vue&#xff0c;大厂或是高级工程师面试的时候究竟会碰到什么棘手或是难缠的 Vue 的面试题呢&a…

数据结构:LRU Cache

数据结构&#xff1a;LRU Cache LRU Cache实现类架构setget测试 总代码 LRU Cache cache意为缓存&#xff0c;硬件层面指CPU与主存之间的缓存&#xff0c;用于减缓两者之间的速度差距。广义上&#xff0c;可以把cache简单理解为一个临时存储区域。 cache的容量是非常有限的&a…

从0到1掌握大模型

人人都看得懂的大模型简介 大模型就像一座庞大的图书馆&#xff0c;里面有非常多的书籍。但与普通图书馆不同的是&#xff0c;这座图书馆中的每本书都是关于不同事物的描述和知识。而这些书籍中的每一页都代表了这个事物的一些特征或细节。现在&#xff0c;想象一下&#xff0…

前端文件流导出

1、前端代码 ​ /** 导出 */ const handleExport async () > {let config {responseType: blob,headers: {Content-Type: application/json,},};const res await getTargetExport(config);const blob new Blob([res]);const fileName PK目标跟进导出列表.xls;const li…

基于Python绘制一个三角形

一、程序 import turtledef draw_triangle(side_length):# 初始化turtle对象并设置速度my_turtle turtle.Turtle()my_turtle.speed(1)# 绘制三角形for _ in range(3):my_turtle.forward(side_length)my_turtle.left(120)# 结束后关闭窗口防止立即退出turtle.done()# 设定三角…

前端面试经验总结1(简历篇)

本文分为3部分&#xff0c;分别为第一部分简历篇&#xff0c;第二部分经典问题篇以及第三部分知识体系篇&#xff0c;都是个人面试经验及同行面试经验总结和整理。 我对于简历的理解是这样的&#xff0c;简历的作用是让看简历的人能够快速、准确地捕捉到有用信息&#xff1a; 你…

【MATLAB源码-第274期】基于matlab的高阶累积量矩阵和PCA的JADE算法在盲信号分离中的应用仿真,输出源信号,混合信号和分离信号。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 基于高阶累积量矩阵和主成分分析&#xff08;PCA&#xff09;的JADE算法是一种典型的盲源分离算法&#xff0c;在信号处理领域中&#xff0c;广泛应用于分离混合信号的独立源。盲源分离问题的核心在于从观测信号中提取出源信…

【C语言】动态内存管理(下)

本篇博客将讲解以下知识&#xff1a; 1、calloc和realloc 2、常见的动态内存错误 1、calloc和realloc &#xff08;1&#xff09;calloc C语言中还提供了一个函数叫calloc&#xff0c;calloc也用来动态内存分配 calloc函数原型&#xff1a; void* calloc(size_t num, …

基于springboo+vue+mysql私人西服定制设计与实现(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…