当前位置: 首页 > news >正文

Go语言新手村:轻松理解变量、常量和枚举用法

Go语言新手村:轻松理解变量、常量和枚举用法

1. 介绍

1.1 发展

2007年,Google开始着手开发Go语言。

2009年11月,Google发布了Go语言的第一个稳定版本,即Go 1.0。这标志着Go语言正式面世,并开始逐渐受到广泛关注和应用。

2011年5月,Go 1.0.2发布,这是Go语言的第一个正式稳定版本,其中包括了一些重要的bug修复和改进。

2018年8月,Go 1.11发布,引入了模块支持、WebAssembly支持、延迟函数调用等特性,这些特性使得Go语言在项目管理、跨平台应用和异步编程等方面有了更加强大的能力。

2021年2月,Go 1.16发布,加入了对模块和错误处理的改进、垃圾回收器的性能提升等特性,这些改进使得Go语言在性能、可靠性和开发体验等方面有了更大的提升。

1.2 特点

  • 高效性:Go语言具有高效的编译速度、并发处理能力和内存管理机制,适合处理高并发、高吞吐量的场景。
  • 并发性:Go语言提供了原生的并发编程模型,通过协程(goroutine)和通道(channel)实现了轻量级的线程管理和通信,使得编写并发程序变得更加容易。
  • 安全性:Go语言内置了安全性特性,例如强类型、空指针检查、内存自动管理等,减少了安全漏洞和错误的可能性。
  • 跨平台:Go语言支持多种操作系统和CPU架构,可以轻松地在不同平台之间进行开发和部署。

2. 基础概念

2.1 内建变量类型

Go 语言中内建变量类型分为三种,分别是布尔类型、数值类型和字符串类型

  1. 布尔类型:布尔类型的关键字是bool,取值范围是true 或 false,其中默认值为false
  2. 数值类型:Go 语言中数值类型很多,包括整数、浮点数、复数。这三种数值类型还有不同的长度。其中整型不仅有不同长度,还分为有符号整数(int)和无符号整数(uint)
类型描述大小范围
int平台相关有符号整数32位或64位根据平台变化
int88位有符号整数8位-128 到 127
int1616位有符号整数16位-32768 到 32767
int3232位有符号整数32位-2147483648 到 2147483647
int6464位有符号整数64位-9223372036854775808 到 9223372036854775807
uint平台相关无符号整数32位或64位根据平台变化
uint8 (byte)8位无符号整数8位0 到 255
uint1616位无符号整数16位0 到 65535
uint3232位无符号整数32位0 到 4294967295
uint6464位无符号整数64位0 到 18446744073709551615
uintptr存储指针的整数平台相关足够容纳指针值
runeUnicode码点32位等同于 int32
float32单精度浮点数32位指数范围:-126到+127
float64双精度浮点数64位指数范围:-1022到+1023
complex64实部虚部分别32位的复数64位范围同float32
complex128实部虚部分别64位的复数128位范围同float64
  1. 字符串类型:关键字string,默认值为空字符串

在 Go 语言中还有两个特殊的类型,runebyte,它们本质上其实是类型别名。rune 是 int32 的别名,常用于处理文本字符,尤其是非ASCII字符;byte 是 uint8 的别名,常用于处理字节、二进制文本。

2.2 变量

Go 语言中使用 var 关键字定义变量,实例代码如下

func main() {var a intvar b stringvar c bool// 输出结果是该类型的零值(默认值)fmt.Printf("a = %d, b = %q,c = %t \n", a, b, c)a = 100b = "hello"c = true// 延迟赋值fmt.Printf("a = %d, b = %q,c = %t \n", a, b, c)// a = 100, b = "hello",c = true var name string = "张三"var age int = 18// 立刻赋值fmt.Printf("name = %s, age = %d \n", name, age)// name = 张三, age = 18 var country = "中国"var price = 100// 类型推导fmt.Printf("country = %s, price = %d \n", country, price)// country = 中国, price = 100 // 短变量声明year := 2025province, city := "江苏省", "苏州市"fmt.Printf("year = %d, province = %s, city = %s \n", year, province, city)// year = 2025, province = 江苏省, city = 苏州市 x, _ := anonymous()fmt.Println(x)// 李四_, y := anonymous()fmt.Println(y)// 20
}func anonymous() (string, int) {return "李四", 20
}

在这一段代码中,展示了Go语言中的变量声明核心概念,下面来详细介绍一下。

  1. 零值初始化:Go为所有基础类型提供零值保障,避免未初始化风险
var a int     // 未显式赋值 → 默认零值:0
var b string  // 未显式赋值 → 默认零值:空字符串 ""
var c bool    // 未显式赋值 → 默认零值:falsefmt.Printf("a = %d, b = %q, c = %t \n", a, b, c) 
// 输出:a = 0, b = "", c = false
  1. 运行时动态修改值:变量在声明后随时修改变量值,但是变量类型固定后不可变更。
a = 100        // 整型赋值
b = "hello"    // 字符串赋值
c = true       // 布尔赋值fmt.Printf("a = %d, b = %q, c = %t \n", a, b, c)
// 输出:a = 100, b = "hello", c = true
  1. 声明时赋值:在声明变量时立刻给变量赋值
var name string = "张三"  // 显式声明string类型
var age int = 18         // 显式声明int类型fmt.Printf("name = %s, age = %d \n", name, age)
// 输出:name = 张三, age = 18
  1. 类型推导:声明时省略变量类型且立刻赋值,编译器根据赋值自动推断类型
var country = "中国"  // 自动推导为string类型
var price = 100      // 自动推导为int类型fmt.Printf("country = %s, price = %d \n", country, price)
// 输出:country = 中国, price = 100
  1. 短变量声明:在函数内部快速声明并初始化变量的方式,并能自动推导类型
	year := 2025			// 等价于 var year int = 2025province, city := "江苏省", "苏州市"		// 多变量同时声明fmt.Printf("year = %d, province = %s, city = %s \n", year, province, city)// year = 2025, province = 江苏省, city = 苏州市
  1. 匿名变量:在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量。 匿名变量用一个下划线_进行占位。匿名变量不占用命名空间,不会分配内存
func anonymous() (string, int) {return "李四", 20
}func main {x, _ := anonymous()			fmt.Println(x)// 李四_, y := anonymous()fmt.Println(y)// 20
}

2.3 常量

常量使用 const 关键字进行声明。其基本语法与 var 声明类似。常量是在编译时就确定其值,并且在程序运行期间不可更改的标识符,所以常量在声明时必须赋值,且不可更改。

枚举

在 Go 语言中,虽然没有像其他编程语言(如 Java 或 C#)那样直接提供 enum 关键字来定义枚举类型,但可以通过使用 const 关键字结合 iota 标识符实现类似的功能。所以枚举值也可以看作一种特殊的常量类型。

iota 是 Go 语言中的一个特殊标识符,仅在 const 声明块中有效。它代表了从 0 开始的连续整数值。每当 const 声明块中出现新的一行(以换行符分隔),iota 的值就自动递增 1。这种机制非常适合用来定义枚举值。

// 定义星期几的枚举值
const (Sunday    = iota // 0Monday           // 1Tuesday          // 2Wednesday        // 3Thursday         // 4Friday           // 5Saturday         // 6
)func main() {fmt.Println("Sunday =", Sunday)fmt.Println("Monday =", Monday)fmt.Println("Tuesday =", Tuesday)fmt.Println("Wednesday =", Wednesday)fmt.Println("Thursday =", Thursday)fmt.Println("Friday =", Friday)fmt.Println("Saturday =", Saturday)
}

除了简单的递增序列,iota 还可以与其它表达式结合使用,生成更加复杂的枚举值。

  1. 指定起始值
const (a = iota + 1 // 1b            // 2c            // 3
)
  1. 跳过某些值
const (_ = iota // 忽略第0个值a        // 1_        // 忽略第2个值b        // 3
)
  1. 位操作
const (b = 1 << (10 * iota)				// 1kb													// 1024mb													// 1048576gb													// 1073741824tb													// 1099511627776pb													// 1125899906842624
)

2.4 作用域

Go 也是一种静态语言,静态语言在使用变量之前需要先声明。Go 语言和常见的静态语言一样,存在全局和局部两种作用域,其中全局作用域在Go语言中也被称为包级作用域。无论是变量 (var) 还是常量 (const),它们的作用域都遵循完全相同的规则,主要取决于它们声明的位置

包级作用域 (Package-Level Scope)

  • 位置:在任何函数、方法或代码块之外的顶层声明。
  • 生命周期:从程序启动时创建,到程序结束时销毁。

局部作用域 (Local Scope)

  • 位置:在函数内部方法内部代码块内部(如 if, for, switch 语句的 {} 内部)声明。
  • 生命周期:从声明/初始化点开始,到包含它的函数、方法或代码块执行结束时终止。

接下来通过示例介绍一下包级变量的声明以及赋值,常量同理。

package mainimport "fmt"// 单独声明(使用零值)
var a int // 零值为 0// 声明并显式赋值
var b string = "hello"// 声明并使用类型推导
var c = true // 推导为 bool// 使用 var() 块集中声明
var (name     string        // 仅声明,零值 ""age      int           // 仅声明,零值 0country  string = "中国" // 声明并赋值province, city = "江苏", "苏州" // 多变量声明并赋值,类型推导
)func main() {// 包级变量在整个包内(包括main函数)都可访问fmt.Printf("a = %d, b = %s, c = %t \n", a, b, c)// 输出:a = 0, b = hello, c = true // 可以在函数内部修改包级变量的值name = "张三"age = 18fmt.Printf("name = %s, age = %d, country = %s, province = %s, city = %s \n", name, age, country, province, city)// 输出:name = 张三, age = 18, country = 中国, province = 江苏, city = 苏州
}

这里主要介绍了四种包级变量的声明方式

在前一节中有一个短变量声明,短变量声明只能声明局部变量

方式示例适用场景
零值声明var a int需要默认值时
显式类型初始化var b string = "hello"明确指定类型避免歧义
类型推导var c = true右侧值类型明确时简化代码
分组声明var (...)组织相关变量,增强可读性
包级变量的导出

在 Go 语言中,包级变量是指那些在包的顶层声明的变量,即不在任何函数内部声明的变量。这些变量可以在整个包内访问,并且如果它们的名字以大写字母开头,则还可以被其他包通过导入的方式访问。这种机制是 Go 实现封装和模块化的重要部分。

假设我们有一个名为 other 的包,其中包含了一些可导出的变量。

package other// 这是一个可导出的包级变量,因为它以大写字母开头
var ExportedVar = "This is an exported variable"// 这个变量不可导出,因为它以小写字母开头
var unexportedVar = "This is a unexported variable"

然后,在另一个文件或项目中,你可以这样导入并使用 other 包中的可导出变量:

package mainimport ("fmt""go-learning/other"
)func main() {fmt.Printf("可导出变量:%s \n", other.ExportedVar)// 可导出变量:This is an exported variable// 尝试访问不可导出的包级变量(会导致编译错误)// fmt.Println(other.unexportedVar) // Error:Cannot use the unexported variable 'unexportedVar' in the current packageother.ExportedVar = "这是修改后的可导出变量"fmt.Printf("修改后的可导出变量:%s \n", other.ExportedVar)// 修改后的可导出变量:这是修改后的可导出变量}
包级变量的修改

直接修改其他包中的变量虽然可行,但不推荐,因为这会导致代码的耦合性增加,难以维护。通常,我们通过函数来封装对变量的访问和修改,这样可以加入额外的逻辑(如验证、加锁等)。

package otherimport "sync"// 这是一个可导出的包级变量,因为它以大写字母开头
var ExportedVar = "This is an exported variable"// 这个变量不可导出,因为它以小写字母开头
var unexportedVar = "This is a unexported variable"var (mu sync.Mutex          	// 内部锁(不可导出)
)// UpdateVal 安全修改配置的函数
func UpdateVal(newString string) {mu.Lock()defer mu.Unlock()ExportedVar = newString
}
package mainimport ("fmt""go-learning/other"
)func main() {fmt.Printf("可导出变量:%s \n", other.ExportedVar)other.UpdateVal("这是安全修改后的可导出变量")fmt.Printf("安全修改后的不可导出变量:%s \n", other.ExportedVar)// 安全修改后的不可导出变量:这是安全修改后的可导出变量 
}

3. 小结

本文介绍了Go语言的基础类型、变量与常量的定义和作用域。讲解了包级与局部作用域的区别,以及可导出变量/常量的规则。

http://www.xdnf.cn/news/1209331.html

相关文章:

  • 从centos更换至ubuntu的安装、配置、操作记录
  • 【iOS】类扩展与关联对象
  • 嵌入式学习日志(十一)
  • Kafka——消费者组重平衡全流程解析
  • 数据库-索引
  • 13、select_points_object_model_3d解析
  • 安卓逆向2-安卓刷机和获取root权限和安装LSPosed框架
  • Linux安装ragflow(含一键安装脚本)
  • vue中使用wavesurfer.js绘制波形图和频谱图
  • sqli-labs通关笔记-第25关GET字符注入(过滤or和and 脚本法)
  • buuctf_crypto26-30
  • 基于变频与移相混合控制(PFM+PSM)的全桥LLC谐振变换器仿真模型
  • 车载诊断架构 --- 关于诊断时间参数P4的浅析
  • QML 3D曲面图(Surface3D)技术
  • K-近邻算法(KNN算法)的K值的选取--交叉验证+网格搜索
  • 【C++算法】72.队列+宽搜_二叉树的最大宽度
  • adb reboot 与 adb shell svc power reboot 的区别
  • 【C++】1. C++基础知识
  • 【HTML】浅谈 script 标签的 defer 和 async
  • 企业高性能web服务器
  • EnergyMath芯详科技 EMS4100/MES4000/MES3900
  • 如何保证DoIP的网络安全?
  • 基于 xlsx-js-style 的 Excel 导出工具实现导出excel
  • 40+个常用的Linux指令——下
  • haproxy应用详解
  • 从github同步新项目的两次挫折-2025.7.29
  • 【WRF工具】服务器中安装编译GrADS
  • 信创国产Linux操作系统汇总:从桌面到服务器,百花齐放
  • 【Golang】Go语言Map数据类型
  • 随缘玩 一: 代理模式