Go 语言中的变量和常量

这篇文章已经放到腾讯智能工作台的知识库啦,链接在这里:ima.copilot-Go 入门到入土。要是你有啥不懂的地方,就去知识库找 AI 聊一聊吧。

1、变量的声明与使用

我们来探讨编程语言中最核心的概念之一:变量

1、静态语言中的变量特性

Go 是一种静态类型语言,其变量处理方式与 Python 等动态语言有显著差异。对于没有静态语言背景的开发者来说,需要特别注意以下几点:

  1. 必须先声明后使用:任何变量都必须先经过声明,才能在代码中使用。

  2. 类型固定:在声明变量时,其类型就已经确定。

  3. 类型不可变:一旦类型确定,就不能再赋予其他类型的值。例如,一个整型(int)变量不能被赋值为字符串(string)。

这种强类型约束使得编译器能在编译阶段就发现许多潜在的错误,有助于编写更健壮、更规范的大型项目。

2、变量的声明方式

Go 语言提供了多种声明变量的方式。

2.1 标准声明 (var)

这是最基础的声明方式。使用 var 关键字,后跟变量名和类型。

image.png

注意:Go 的类型声明位于变量名之后,这与其他静态语言(如 C++ 或 Java)不同。建议直接适应这种语法,无需纠结其设计原因。

2.2 声明并初始化

可以在声明变量的同时为其赋予初始值。

image.png

当提供初始值时,Go 可以自动推断类型,因此可以省略类型声明:

image.png

2.3 短变量声明 (:=)

这是 Go 中最常用、最简洁的声明方式,它会合并声明和初始化两个步骤。

image.png

这种方式只能用于局部变量(在函数内部声明的变量),不能用于全局变量。在日常开发中,你会频繁地使用这种方法。

3、全局变量与局部变量

3.1 全局变量

在函数体外声明的变量,其作用域覆盖整个包。

image.png

3.2 局部变量

在函数体内声明的变量,其作用域仅限于该函数内部。

image.png

注意:短变量声明 := 不能用于声明全局变量。

4、多变量生成

Go 支持在一行内声明多个变量。

image.png

5、变量使用的注意事项

  1. 变量名冲突:在同一作用域(代码块)内,不能重复声明同名变量。但局部变量可以与全局变量同名,此时局部变量会“覆盖”全局变量。

  2. 零值 (Zero Value):在 Go 中,变量在声明后若未被显式初始化,会被自动赋予其类型的零值。这避免了在其他语言中可能出现的“随机值”问题。

  • int: 0

  • string: "" (空字符串)

  • bool: false

  • 指针、接口、切片、映射、通道:nil

image.png

  1. 声明后必须使用:Go 语言强制要求,局部变量在声明后必须被使用,否则会在编译时报错。此举旨在鼓励编写整洁、无冗余的代码。全局变量则无此限制。

image.png

2、常量的定义和使用

在 Go 语言中,常量(Constant)是指在程序编译时就已确定,并且在运行时不能被修改的固定值。当程序中有些值从始至终都不应改变时,将其定义为常量是最佳实践。这可以有效防止在代码的某个地方无意中修改了重要的值。

1、常量的基本定义

常量的定义与变量类似,但使用 const 关键字。

image.png

核心特性:

  • 不可变性:常量一旦声明,其值就不能再被修改。任何尝试对常量重新赋值的行为都会导致编译错误。

image.png

2、常量的类型

常量也具有类型。Go 语言支持在定义常量时显式指定类型,也支持通过值进行隐式类型推断。

2.1 显式定义

明确指定常量的类型。

image.png

2.2 隐式定义

不指定类型,由编译器根据所赋的值自动推断。

image.png

在这种情况下,编译器会自动推断 E 的类型。

3、命名规范

为了在代码中清晰地区分常量和变量,Go 语言的开发社区遵循以下命名规范:

  • 常量名全部大写

  • 如果常量名由多个单词组成,使用下划线 _ 分隔

image.png

虽然这并非强制性语法,但遵循此规范可以极大地提高代码的可读性

4、分组定义常量

为了代码的整洁和可读性,当需要定义多个相关的常量时,可以使用括号 () 将它们分组。

image.png

分组定义时,存在一个重要的特性:在一组常量中,如果某个常量没有被显式赋值,它会自动沿用上一个常量的值和类型。

看下面的例子:

image.png

当我们打印这些常量时,会得到 16, 16, "abc", "abc", "abc"

对这个特性的理解,是掌握 Go 中另一个重要关键字 iota 的基础,我们将在后续文章中详细讲解。

5、常量定义的核心规则总结

  1. 支持的类型:常量只能是布尔类型、数值类型(整数、浮点数、复数)和字符串类型。其他更复杂的类型(如 structarray)不支持定义为常量。

  2. 无需强制使用:与变量不同,如果定义了一个常量但从未使用它,编译器不会报错。

  3. 类型一致性:如果显式指定了常量的类型,那么赋予它的值必须与该类型兼容。

3、Go 语言中的 iota 详解

iota 是 Go 语言中一个非常有用的关键字,专用于常量的定义。它可以被看作一个可由编译器在编译期间修改的特殊常量。iota 的主要作用是简化具有递增规律的常量的定义,尤其在定义枚举值、错误码等场景中,能显著提高代码的可读性和可维护性。

1、iota 的基本用法

iota 的值由编译器控制,它从 0 开始,在同一个 const 定义组中,每增加一个常量声明,其值就会自动加 1。

image.png

2、iota 的隐式特性与简化写法

Go 语言的 const 声明有一个特性:如果某一行没有指定值,它会自动沿用上一行的表达式。这个特性与 iota 结合使用,可以写出非常简洁的代码。

你只需要在第一个常量上使用 iota,后续的常量会自动应用递增的

image.png

这种写法是 iota 最常用、最推荐的实践。如果后续需要在中间插入新的常量,无需手动修改后续所有常量的值,iota 会自动处理。

3、使用表达式自定义 iota 序列

iota 的强大之处在于它可以参与运算。你可以用它来构建更复杂的常量序列。

例如,让序列从 1 开始:

image.png

4、中断和恢复 iota

如果在 const 组中,你手动为某个常量赋值,那么 iota 的递增在这一行会被中断。但是,iota 的内部计数器仍然会根据行数继续增加。

当你再次使用 iota 时,它会返回当前行对应的计数值,而不是被中断行的值。

image.png

关键点iota 的值取决于它所在的行号(从 0 开始),而不是上一行的常量值。

5、iota 的核心规则总结

  1. const 块重置iota 的计数器在每一个新的 const 关键字出现时都会被重置为 0。

image.png

  1. 行数递增:在 const 块中,每新增一行常量声明(即使该行是空标识符),iota 的计数器就会自动加 1。

  2. 表达式沿用:如果常量定义被省略,它会自动沿用上一行的赋值表达式。

  3. 中断不影响计数:即使某一行不使用 iota,其内部计数器依然会增加。当后续行恢复使用 iota 时,将获取该行对应的计数值。

iota 是 Go 语言中一个精妙的设计,掌握它能让你的代码更加简洁和优雅。

4、匿名变量

在 Go 语言中,有一个非常严格的规则:所有声明的变量都必须被使用,否则编译器会报错。然而,在某些场景下,我们可能需要接收一个值,但又确实不需要使用它。为了解决这个问题,Go 提供了匿名变量(Anonymous Variable)

匿名变量使用一个下划线 _ 来表示,它是一个特殊的变量名,可以看作一个“占位符”。任何赋予匿名变量的值都会被直接丢弃,因此它不需要被使用,也不会引发编译错误。

1、匿名变量的核心用途

匿名变量最常见的用途是处理函数的多个返回值

在 Go 中,一个函数可以返回多个值。当调用这样的函数时,你必须用相应数量的变量来接收所有返回值。但有时,你可能只关心其中的一部分返回值。

场景示例:

假设我们有一个函数 getData(),它返回一个整数和一个布尔值。

image.png

现在,我们只想判断操作是否成功(即只关心返回的布尔值),而对那个整数不感兴趣。

错误的做法:

image.png

正确的做法:使用匿名变量

我们可以使用匿名变量 _ 来接收那个我们不关心的整数值。

image.png

通过这种方式,我们既满足了函数多返回值的接收要求,又避免了因变量未使用而导致的编译错误。

总结

  • 定义:匿名变量是一个下划线 _

  • 作用:作为值的占位符,接收并丢弃你不需要的值,以满足语法要求。

  • 优势:使代码更简洁,可以优雅地忽略不必要的函数返回值或其他值。

在后续学习 Go 的接口(Interface)等更高级的概念时,你还会遇到匿名变量的其他应用场景。掌握它是编写地道 Go 代码的重要一步。

5、变量作用域

在像 Go 这样的静态类型语言中,作用域(Scope) 是一个至关重要的概念。它定义了程序中一个变量可以被访问的区域。与许多动态语言相比,Go 对作用域的规定非常严格,这有助于在编译阶段就发现潜在的错误,从而提高代码的健壮性。

1、全局作用域 (Global Scope)

在所有函数体外部声明的变量,拥有全局作用域。这意味着它们可以在当前包(package)的任何地方被访问和修改。

image.png

2、局部作用域 (Local Scope)

image.png

3、块级作用域 (Block Scope)

Go 语言的作用域规则是基于 代码块的,代码块由花括号 {} 界定。在 ifforswitch 或普通 {} 内部声明的变量,其作用域仅限于该代码块。

这是静态语言中一个非常重要的特性:一旦程序执行离开一个代码块,该块内声明的所有变量都将被销毁,无法在外部访问。

示例 1:普通代码块

image.png

示例 2:if 条件块

image.png

一个常见的误区是,认为如果在 ifelse 的所有分支中都定义了同名变量,那么在外部就可以访问它。这是错误的,因为每个变量的作用域都被限制在各自的代码块内。

image.png

4、总结

  • 全局变量:在整个包内可见。

  • 局部变量:仅在声明它的函数或代码块 {} 内部可见。

  • 严格性:Go 语言严格遵循基于代码块的作用域规则。离开一个代码块,内部变量即失效。

  • 好处:这种严格性可以有效防止变量被意外访问或修改,减少了程序出错的可能性,是静态语言可靠性的重要保障。IDE 和编译器也能基于此规则提供准确的错误提示。

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

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

相关文章

破局传统订货!云徙渠道订货系统赋能企业数字化渠道升级

在数字化浪潮的推动下,传统经销商订货模式面临着诸多挑战,如信息孤岛、系统崩溃、移动化不足等问题。云徙渠道订货系统凭借其创新的数字化架构和强大的功能模块,正在成为企业实现渠道数字化转型的重要工具。 系统功能与创新 云徙渠道订货系统…

SQL关键字三分钟入门:UNION 与 UNION ALL —— 数据合并全攻略

在处理数据时,有时我们需要将来自不同表或同一表的不同查询结果合并在一起。例如: 合并两个部门的员工名单;将多个地区的销售数据汇总;显示某段时间内所有新增和修改的记录。 这时候,我们就需要用到 SQL 中非常强大的…

SNMPv3 的安全命名空间详解

1. 安全命名空间的本质 安全命名空间是 SNMPv3 的核心安全机制,通过 上下文(Context) 实现: #mermaid-svg-6cV9146nTFF1zCMJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#merma…

【嵌入式硬件实例】-555定时器实现烟雾和易燃气体泄露检测

555定时器实现烟雾和易燃气体泄露检测 文章目录 555定时器实现烟雾和易燃气体泄露检测1、555定时器介绍2、MQ-2 气体/烟雾传感器模块介绍3、硬件准备与接线在本文中,我们将使用555定时器和MQ-2气体传感器构建一个气体泄漏检测和报警系统。它在煤气泄漏期间用作家庭安全警报器。…

【机器人】DualMap 具身导航 | 动态场景 开放词汇语义建图 导航系统

DualMap 是一个在线的开放词汇语义映射系统,使得机器人能够通过自然语言查询在动态变化的环境中理解和导航 双地图导航,结合全局抽象地图进行高层次候选选择,以及局部具体地图进行精确目标定位,有效管理和更新环境中的动态变化。…

【Fifty Project - D37】

fifty project算是失败了一半了 成功的那一半在于一定程度上拯救了我的作息和健康,两个月前入职体检的肝有点不健康,昨天复查发现全都回到了健康范围!尿酸也在正常范围!就是体重还是没减下来hhh 失败的一半在于自己很差劲的规划能…

解码危险品物流背后的“隐形防线”

当急救药品跨越千里送达医院,当新能源电池准时抵达生产线,当化工原料安全运往工厂……这些与日常生活息息相关的场景背后,有一群人始终在和时间赛跑,与风险博弈。他们不是超级英雄,而是危险品物流从业者——一个鲜少被…

Flutter Melos在外包团队协作中的弊端与应对策略

引言 在大型Flutter项目开发中,Melos作为一款优秀的Monorepo管理工具,能够有效协调多包项目的开发流程。然而,当项目涉及外包团队协作时,Melos的使用会面临一系列独特的挑战。本文将深入分析Flutter Melos在外包团队协作环境中的…

<selectKey> 中的order 属性

在 MyBatis 中&#xff0c;<selectKey> 标签的 order 属性用于指定生成主键值的 SQL 语句执行时机。 除了 AFTER&#xff0c;MyBatis 还支持另一种模式&#xff1a;BEFORE&#xff0c; 它们有明确的使用场景和区别&#xff1a; order"AFTER" 适用数据库&#x…

BitsAndBytes(简称 BnB)是一个用于“压缩”大语言模型的工具包

BitsAndBytes&#xff08;简称 BnB&#xff09;是一个用于“压缩”大语言模型的工具包&#xff0c;能把模型从原来的16位或32位&#xff0c;压成4位或8位&#xff0c;减少显存占用&#xff0c;同时保持尽量高的精度。 &#x1f9e9; 为什么叫 Bits and Bytes&#xff1f; 它的…

【前端】 Vue 3 中二次封装组件

在 Vue 3 中二次封装组件是提高代码复用性和维护性的重要手段。以下是详细的封装方法和最佳实践&#xff1a; 一、封装原则 功能扩展&#xff1a;在原有组件基础上添加新功能定制样式&#xff1a;统一项目的 UI 设计规范简化接口&#xff1a;隐藏复杂逻辑&#xff0c;提供简洁…

分布式词表示(Distributed Word Representation):自然语言处理的核心基石

分布式词表示&#xff08;Distributed Word Representation&#xff09;&#xff1a;自然语言处理的核心基石 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;如何将离散的词汇转化为计算机可理解的数值形式&#xff0c;一直是技术突破的关键。传统的独热编码&…

Windows Playwright NotImplementedError问题深究

原文链接&#xff1a;Windows Playwright NotImplementedError问题深究 < Ping通途说 0. 引言 今天来看一下这个困扰我很久的问题。是关于在FastAPI / NiceGUI 等基于Uvicorn环境下使用Async Playwright 提示NotImplementedError的问题。 本解决方案仅适用基于Uvicorn的异步…

QCustomPlot 数据可视化方式详解

QCustomPlot 数据可视化方式详解 QCustomPlot 提供了多种灵活的数据显示方式,可以满足从简单静态图表到复杂实时数据可视化的各种需求。以下是 QCustomPlot 显示数据的核心方式和策略: 基本数据显示方式 1.1 完整数据设置 (setData)// 一次性设置完整数据集 QVector<doub…

家用旧电脑搭建小型服务器操作步骤教程:一步一步本地部署到公网访问

你家是不是也有一台吃灰的旧电脑&#xff1f;别急着扔&#xff0c;它其实还能发挥大作用&#xff01;小编最近就把家里一台十年前的老台式机&#xff0c;改造成了一个小型服务器&#xff0c;主要用来文件备份、当网站测试环境&#xff0c;还是比较有用的。今天就来手把手教你&a…

Python银行账户系统全解析

完整代码如下&#xff1a; class BankAccount:def __init__(self, account_holder, initial_balance0):"""初始化银行账户:param account_holder: 账户持有人姓名:param initial_balance: 初始余额&#xff0c;默认为0"""self.account_holder …

博世X阿里云:智能座舱接入通义大模型!

近日,全球领先的汽车技术与服务商博世与阿里云宣布在大模型领域达成合作,通义大模型助力博世加速AI技术应用于智能座舱,首次实现座舱环境主动感知和3D数字人交互。 博世AI智能座舱技术原型由博世智能驾控事业部以通义千问和通义万相为基础,结合阿里云百炼大模型服务平台和磐曦数…

高性能计算服务器的主要作用都有哪些?

高性能计算服务器是一种专门为了处理大规模科学计算和数据分析任务所设计的服务器&#xff0c;高性能计算服务器拥有着强大的计算能力和高速的数据传输能力&#xff0c;有着高度的可靠性和可扩展性&#xff0c;下面小编就来介绍一下高性能计算服务器的主要作用吧&#xff01; 高…

C++ 进阶:深入理解虚函数、继承与多态

前言 在 C 的面向对象编程中&#xff0c;继承和多态是两个核心概念。今天我们将深入探讨 C 中与多态密切相关的几个重要特性&#xff1a;虚函数、virtual 关键字、override 关键字、多重继承以及虚继承。这些内容是理解 C 多态机制和复杂类层次结构的关键。 虚函数与 virtual…

为AR眼镜等多种智能可穿戴设备添加穿戴状态检测功能

作者&#xff1a;Azoteq中国 随着AR/VR眼镜、头戴式耳机和入耳式耳塞、智能手表和健身手环等可穿戴电子产品受到越来越多消费者的欢迎&#xff0c;如何设计外形更加时尚迷人、功能更加先进宜人的穿戴产品成为了创新和创意的焦点。作为全球领先的多传感器解决方案提供商&#xf…