Go语言基本语法(四)函数与变量的作用域

函数

Go语言中的函数(Function)是执行特定任务的代码块,它们是构建程序的基本单位之一。函数可以接受输入参数,执行一系列操作,并可返回结果。Go语言的函数设计简洁,强调代码的清晰度和模块化。下面是Go函数的一些关键特征和一个示例说明:

Go函数的特征:

  1. 定义格式:函数以func关键字开始,后面跟着函数名、参数列表(如果有的话)、返回值列表(如果有的话),最后是函数体。

  2. 参数与返回值:函数可以有零个、一个或多个参数,以及零个、一个或多个返回值。参数和返回值的类型需明确指定。

  3. 多值返回:Go语言支持函数返回多个值,这是一个强大的特性,可以用来避免错误码或使用额外的输出参数。

  4. 匿名函数与闭包:Go语言支持匿名函数(也称作lambda函数)和闭包,它们可以捕获其定义时的上下文变量,提供灵活的编程能力。

  5. defer、panic与recover:Go提供了异常处理机制,通过defer来注册延迟执行的函数,panic用于抛出异常,recover则用于捕获并恢复从panic产生的异常流程。

示例说明:

下面是一个简单的Go函数示例,该函数接受两个整数作为参数,返回它们的和与差。

package main

import "fmt"

// 这是一个加减法函数,接受两个int类型的参数,返回两个int类型的值(和与差)
func calculateSumAndDifference(a, b int) (sum int, difference int) {
    sum = a + b
    difference = a - b
    return // 自动返回sum和difference
}

func main() {
    // 调用calculateSumAndDifference函数
    sum, diff := calculateSumAndDifference(10, 5)
    fmt.Printf("Sum: %d, Difference: %d\n", sum, diff) //输出Sum: 15, Difference: 5
}

形参与实参:

形参与实参是函数调用中两个重要的概念,它们描述了函数参数的两个方面:

形参(形式参数, Formal Arguments)

  • 定义:形参是在定义函数时,在函数签名的括号内声明的参数。它们是一组占位符,代表将来调用函数时将要传递的具体值的位置。形参在函数体内部使用,用于接收调用者提供的数据。
  • 特性
    • 形参仅在函数内部有效,其生命周期局限于函数执行期间。
    • 形参在函数未被调用时并不占用实际的存储空间,只有在函数调用发生时,根据实参分配相应的内存。
    • 形参的名称供函数内部使用,调用者不需要知道形参的名字。
// 函数定义
func addNumbers(x int, y int) int {
    sum := x + y
    return sum
}

在这个例子中:

  • x 和 y 是形参(形式参数)。它们是函数定义的一部分,用来指定函数需要接收什么样的数据输入。这里,x 和 y 都是整型(int)变量,代表将来调用此函数时用户需要提供的两个整数值的位置。

实参(实际参数, Actual Arguments)

  • 定义:实参是在调用函数时,实际传递给函数的具体值或变量。这些值或变量用来给形参赋值,使得函数能够使用这些数据进行操作。
  • 特性
    • 实参可以是常量、变量、表达式或其它函数的返回值。
    • 调用函数时,实参的值(或地址,对于指针或引用类型)被复制给对应的形参。
    • 实参在调用函数之前必须已经初始化,即具有确定的值。
    • 实参的生命周期独立于函数调用,它们可能在函数调用之前就已经存在,并且在函数调用结束后继续存在。
// 函数调用
result := addNumbers(3, 4)
fmt.Println(result) // 输出结果:7

在函数调用中:

  • 3 和 4 是实参(实际参数)。它们是调用函数时传递给函数的具体数值。在这里,我们将 3 赋给了形参 x,将 4 赋给了形参 y。函数内部,这些实参的值被用来执行计算,然后返回结果。

两者的关系

  • 匹配:在函数调用时,实参的数量、类型和顺序必须与形参一一对应,否则会导致编译错误。
  • 数据传递:调用函数时,实参的值(对于值类型)或引用(对于引用类型)被传递给形参。对于基本数据类型,这种传递是值传递,即形参接收到的是实参的一个副本;而对于指针或引用类型,则是引用传递,形参和实参共享同一份数据的地址。
  • 作用域:形参的作用域局限在函数内部,而实参的作用域则取决于它们在程序中的定义位置,可以是全局的,也可以是局部的。

匿名函数

匿名函数是没有名字的函数,它们可以直接在代码中定义并立即使用,通常作为值传递给其他函数或赋值给变量。匿名函数的语法简洁,形式如下:

add := func(a, b int) int {
    return a + b
}

在这个例子中,add变量被赋予了一个匿名函数,这个函数接受两个整数参数并返回它们的和。

闭包函数

闭包是Go语言中匿名函数的一个特例,它不仅包含了函数体,还携带了对其定义时周围变量(自由变量)的引用。这意味着闭包可以访问并修改在其外部作用域中定义的变量,即便这些变量在原始作用域之外已经不再存在。闭包使得函数能够“记住”它被创建时的环境。

闭包的一个典型应用场景是返回一个函数,这个返回的函数能继续访问并操作外部函数的局部变量:

func counter() func() int {
    count := 0 // 这是一个自由变量,被闭包捕获
    return func() int {
        count++
        return count
    }
}

increment := counter()
fmt.Println(increment()) // 输出:1
fmt.Println(increment()) // 输出:2

变量作用域

  1. 局部作用域

    • 在函数体内声明的变量被称为局部变量。它们仅在该函数内部可见,并且在函数执行结束后自动释放。
    • 块作用域:即使是函数内部更小的代码块(如if语句、for循环等内部),声明的变量也只能在该块及其嵌套的子块中访问。
    • 函数参数也是局部变量,它们的作用域限制在该函数内部。
package main

import "fmt"

func main() {
	// 这是一个局部变量
	var localVar int = 50
	fmt.Println("局部变量的值:", localVar) //局部变量的值: 50
	incrementLocalVar(localVar)
	// 注意:即使在incrementLocalVar内部修改了localVar的值,这里的值也不会改变
	fmt.Println("原局部变量的值(未改变):", localVar) //原局部变量的值(未改变): 50
}

func incrementLocalVar(num int) {
	num = num + 10
	fmt.Println("在函数内部修改后的局部变量的值:", num) //在函数内部修改后的局部变量的值: 60
}
  1. 全局作用域

    • 在函数外部定义的变量称为全局变量,它们在整个包内都是可见的。如果在同一个包的不同文件中要访问全局变量,需要使用import语句中的.操作符来导入该变量所在的文件(尽管通常不鼓励过度使用全局变量)。
    • 全局变量在整个程序生命周期内都存在,且初始化发生在程序启动时。
package main

import "fmt"

// 这是一个全局变量
var globalVar int = 100

func main() {
	fmt.Println("全局变量的值:", globalVar) //全局变量的值: 100
	modifyGlobalVar()
	fmt.Println("修改后的全局变量的值:", globalVar) //修改后的全局变量的值: 110
}

func modifyGlobalVar() {
	globalVar = globalVar + 10
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构(八)----树

目录 一.树的逻辑结构 1.双亲表示法(顺序存储) 2.孩子表示法(顺序链式存储) 3.孩子兄弟表示法(链式存储) 二.树的遍历 1.先根遍历 2.后根遍历 3.层次遍历 三.森林的遍历 1.森林的先序遍历 2.森林的中序遍历 四.哈夫曼…

基于FPGA的数字信号处理(6)--如何确定Verilog表达式的符号

前言 尽管signed语法的使用能带来很多便利,但同时也给表达式的符号确定带来了更多的不确定性。比如一个有符号数和一个无符号数的加法/乘法结果是有符号数还是无符号数?一个有符号数和一个无符号数的比较结果是有符号数还是无符号数?等等。接…

数学建模--图论最短路径基础

1.图的定义 学过数据结构或者离散数学的小伙伴们应该知道图的概念,我在这里简单的介绍一下: 图的概念和我们理解的是很不一样的,这里的图并不是我们的生活里面的图片,而是一种表示不同的数据之间的关系,例如这里的5个…

CMMI认证--基础知识总览

最近公司研发部搞CMMI L5认证,顺便记录下培训内容。 文章目录 一、什么是CMMI二、CMMI作用三、CMMI的成熟度等级四、过程域五、此次CMMI DEV 2.0或3.0特点六、CMMI 评估1、评估方法2、客观证据3、每个过程域如何给出评分等级 七、CMMI规程文件八、CMMI L5将度量统计…

Re69:读论文 LaMDA: Language Models for Dialog Applications

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称:LaMDA: Language Models for Dialog Applications ArXiv网址:https://arxiv.org/abs/2201.08239 本文介绍谷歌提出的对话大模型LaMDA,主要关注对各项指标&#x…

【C 数据结构】深度优先搜索、广度优先搜索

文章目录 【 1. DFS 深度优先搜索 】1.1 基本原理1.2 C 实现 【 2. BFS 广度优先搜索 】2.1 基本原理2.2 C 实现 【 3. 深度优先生成树、广度优先生成树 】【 4. 深度优先生成森林、广度优先生成森林 】4.1 深度优先生成森林4.2 广度优先生成森林 对存储的图中的顶点进行遍历搜…

【信号与系统杂谈 - 1】为什么拉普拉斯变换有收敛域而傅里叶变换没有

这个问题是我在推导傅里叶变换的时移特性公式和拉普拉斯变换的延时特性公式时发现的(即拉氏变换总是需要考虑收敛域的原因) 援引知乎上的回答解释

12_Scala_package

文章目录 Scaal面向对象编程1.回顾Java2.package可以多次声明3.设置作用域,设置上下级4.包可以当作对象使用5.import6.Scala用_取代Java *7.导入多个包8.屏蔽类9.类起别名10.import的规则11.有些包无需导入 Scaal面向对象编程 Scala是一门完全面向对象语言&#xf…

C# winform 漂亮的日期时间控件

源代码下载: https://download.csdn.net/download/gaoxiang19820514/89242240 效果图 在 HZH-Controls控件 基础上修改的日期控件 因为HZH_Controls控件 中的日期控件太大了, 我的程序中需要多个日期时间的控件放不下,主题是绿色的&#…

Springboot+Vue项目-基于Java+MySQL的校园疫情防控系统(附源码+演示视频+LW)

大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &…

力扣刷题Day2

题目链接: 24. 两两交换链表中的节点 - 力扣(LeetCode) 效果: 解题思路: 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 注意不可以只是单纯的改变节点内部的值,而…

Docker--compose概述与部署

目录 一、概述 1. Compose简介 1.1 docker compose常用命令 1.2 Compose配置常用字段 2. YAML简介 2.1 YAML支持的数据结构 2.2 YML文件编写注意事项 2.3 Docker Compose文件结构 3. Docker-Compose安装 ​编辑 4.docker Compose撰写nginx 镜像 1. 准备环境 ​编辑…

苹果和OpenAI再续前缘,iOS 18会是颠覆级的吗?|TodayAI

据彭博社最新报道,苹果公司已经与人工智能领域的先锋企业OpenAI重启了对话,双方目前正在讨论一项可能的合作,以将OpenAI的生成式人工智能技术整合到苹果即将推出的iOS 18操作系统中。这一举措表明,苹果正加速其在人工智能技术上的…

【EI会议|稳定检索】2024年传感技术与图像处理国际会议(ICSTIP 2024)

2024 International Conference on Sensing Technology and Image Processing 一、大会信息 会议名称:2024年传感技术与图像处理国际会议会议简称:ICSTIP 2024收录检索:提交Ei Compendex,CPCI,CNKI,Google Scholar等会议官网:htt…

final原理

文章目录 1. 设置 final 变量的原理2. 获取 final 变量的原理 1. 设置 final 变量的原理 理解了 volatile 原理,再对比 final 的实现就比较简单了 public class TestFinal {final int a 20; }字节码 0: aload_0 1: invokespecial #1 // Method java/lang/Object…

数组 Leetcode 704 二分查找/Leetcode 59 螺旋矩阵/Leetcode 203移除链表元素

数组 Leetcode 704 二分查找 Leetcode 704 学习记录自代码随想录 二分法模板记忆&#xff0c;数值分析中牛顿迭代法 class Solution { public:int search(vector<int>& nums, int target) {int left 0, right nums.size()-1;// 是否需要等于号&#xff0c;假设…

SpringCloud之OpenFeign

学习笔记&#xff1a; 官网地址&#xff1a;https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign 源码&#xff1a;https://github.com/spring-cloud/spring-cloud-openfeign 1、概念总结 OpenFeign是一个声明式的Web服务客户端…

MySql-日期分组

一、分别统计各时间各类型数据条数 数据库的 request_time字段 数据类型&#xff1a;timestamp 默认值&#xff1a;CURRENT_TIMESTAMP 例子&#xff1a; 2024-01-26 08:25:48 原数据&#xff1a; 1、将数据按照日期&#xff08;年月日&#xff09;形式输出 按照request_…

【人工智能基础】聚类实验分析

实验环境&#xff1a;anaconda、jupyter notebook、spyder 实现用到的类库&#xff1a;numpy、matplotlib、scikit-learn k均值聚类&#xff08;K-MEANS&#xff09; k均值聚类的原理&#xff1a; 选定k个聚类中心把数据集中距离聚类中心i最近的点都归属到一个簇根据每个簇中…

debian配置四叶草输入法

效果展示 一、前言 在linux下体验比较好的输入法只有两款&#xff1a;搜狗输入法、四叶草输入法。 ubuntu下可以成功配置搜狗输入法&#xff0c;但debian下从来没有成功过。 今天在用fcitx5 四叶草时发现VNC远程输入法会失灵&#xff0c;于是改用了ibus 四叶草&#xff0c…
最新文章