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

Go语言变量与数据类型完全指南

概述

Go语言以其简洁的类型系统著称,变量声明方式多样,数据类型清晰明了。本文详细介绍Go语言中的变量声明、基本数据类型、类型转换以及可见性规则,帮助读者打下坚实的类型基础。

一、变量声明

1.1 var 声明

标准的变量声明使用var关键字:

// 基本语法 var name string = "张三" var age int = 25 var isStudent bool = true ​ // 类型推断(省略类型) var name = "张三" // 推断为 string var age = 25 // 推断为 int var isStudent = true // 推断为 bool ​ // 声明多个变量 var ( name string age int city string = "北京" )

1.2 短变量声明(:=)

在函数内部,可以使用:=进行短变量声明:

func main() { name := "Go语言" // 等价于 var name string = "Go语言" version := 1.22 // 等价于 var version int = 1.22 price := 99.9 // 等价于 var price float64 = 99.9 fmt.Println(name, version, price) }

重要规则:

  • :=只能在函数内部使用,不能用于全局变量声明

  • 左侧至少有一个变量是新建的,不能全是已存在的变量

// 正确示例 a, b := 1, 2 // 两个都是新建 a, c := 1, 3 // a已存在,c新建 ​ // 错误示例 a, b := 1, 2 // 错误:没有新变量

1.3 常量声明

常量使用const关键字,值在编译时确定:

const Pi float64 = 3.14159 const AppName = "MyApp" // 类型推断 const ( StatusOK = 200 StatusNotFound = 404 StatusError = 500 ) ​ // iota:常量计数器,用于生成枚举值 const ( Sunday = iota // 0 Monday // 1 Tuesday // 2 Wednesday // 3 Thursday // 4 Friday // 5 Saturday // 6 )

1.4 零值机制

Go语言中,未初始化的变量会自动赋零值:

类型零值
数值类型(int, float)0
布尔类型 boolfalse
字符串 string""(空字符串)
指针、切片、map、channel、interfacenil
func main() { var i int var f float64 var b bool var s string var arr []int fmt.Printf("int零值: %d\n", i) fmt.Printf("float零值: %f\n", f) fmt.Printf("bool零值: %t\n", b) fmt.Printf("string零值: '%s'\n", s) fmt.Printf("slice零值: %v (nil: %t)\n", arr, arr == nil) }

输出:

int零值: 0 float零值: 0.000000 bool零值: false string零值: '' slice零值: [] (nil: true)

二、基本数据类型

2.1 整数类型

Go的整数类型分为有符号和无符号两大类:

有符号整数:

类型描述范围
int88位有符号-128 ~ 127
int1616位有符号-32768 ~ 32767
int3232位有符号-2147483648 ~ 2147483647
int6464位有符号-9223372036854775808 ~ 9223372036854775807
int平台相关(32/64位)取决于平台

无符号整数:

类型描述范围
uint88位无符号0 ~ 255
uint1616位无符号0 ~ 65535
uint3232位无符号0 ~ 4294967295
uint6464位无符号0 ~ 18446744073709551615
uint平台相关取决于平台
byteuint8 的别名0 ~ 255
runeint32 的别名(Unicode码点)-2147483648 ~ 2147483647
func main() { // 有符号整数 var a int8 = 127 var b int16 = -128 var c int32 = 2147483647 var d int64 = -9223372036854775808 // 无符号整数 var e uint8 = 255 var f uint16 = 65535 // byte 和 rune var g byte = 65 // ASCII 'A' var h rune = '中' // Unicode码点 fmt.Printf("int8: %d\n", a) fmt.Printf("int16: %d\n", b) fmt.Printf("byte: %c (ASCII 65)\n", g) fmt.Printf("rune: %c (Unicode)\n", h) }

2.2 浮点数类型

类型描述精度
float3232位浮点数约7位十进制数字
float6464位浮点数约15位十进制数字(推荐使用
func main() { var a float32 = 3.1415926 var b float64 = 3.141592653589793 fmt.Printf("float32: %f\n", a) fmt.Printf("float32: %.6f\n", a) fmt.Printf("float64: %.15f\n", b) // 科学计数法 fmt.Printf("float64科学计数: %e\n", b) // 特殊值 fmt.Printf("无穷大: %f\n", math.Inf(1)) fmt.Printf("负无穷: %f\n", math.Inf(-1)) fmt.Printf("NaN: %f\n", math.NaN()) }

2.3 复数类型

Go支持复数运算:

func main() { var c1 complex64 = 1 + 2i var c2 complex128 = 3 + 4i fmt.Printf("c1: %v\n", c1) fmt.Printf("c2: %v\n", c2) fmt.Printf("c1 + c2 = %v\n", c1 + c2) fmt.Printf("c1 * c2 = %v\n", c1 * c2) fmt.Printf("real(c1) = %f, imag(c1) = %f\n", real(c1), imag(c1)) }

2.4 字符串类型

Go字符串是UTF-8编码的不可变字节序列:

func main() { s1 := "Hello, Go!" s2 := "你好,Go语言!" fmt.Println(s1) fmt.Println(s2) // 字符串长度(字节数) fmt.Printf("s1字节长度: %d\n", len(s1)) fmt.Printf("s2字节长度: %d\n", len(s2)) // 字符个数(rune数) fmt.Printf("s2字符个数: %d\n", len([]rune(s2))) // 访问单个字节 fmt.Printf("s1[0] = %c (字节值: %d)\n", s1[0], s1[0]) }

2.5 布尔类型

布尔类型只有两个值:truefalse

func main() { var a bool = true var b bool = false // 短路求值 c := a && b // false(a为true,但b为false) d := a || b // true(a为true,无需计算b) fmt.Printf("a && b = %t\n", c) fmt.Printf("a || b = %t\n", d) fmt.Printf("!a = %t\n", !a) }

三、类型转换

Go语言没有隐式类型转换,必须显式转换:

3.1 数值类型转换

func main() { // int 转 float var i int = 42 var f float64 = float64(i) fmt.Printf("int->float64: %f\n", f) // float 转 int(丢失小数部分) var f2 float64 = 3.99 var i2 int = int(f2) fmt.Printf("float64->int: %d (截断)\n", i2) // int8, int16, int32, int64 互转 var i64 int64 = 1000 var i32 int32 = int32(i64) var i16 int16 = int16(i32) var i8 int8 = int8(i16) fmt.Printf("int64->int8: %d\n", i8) }

⚠️ 溢出问题:

func main() { var i int8 = 127 var i2 int8 = int8(i + 1) // 溢出,结果为-128 fmt.Printf("int8溢出: %d\n", i2) var u uint8 = 255 var u2 uint8 = u + 1 // 溢出,结果为0 fmt.Printf("uint8溢出: %d\n", u2) }

3.2 字符串与字节切片互转

func main() { // string 转 []byte s := "Hello" b := []byte(s) fmt.Printf("[]byte: %v\n", b) // []byte 转 string b2 := []byte{72, 101, 108, 108, 111} s2 := string(b2) fmt.Printf("string: %s\n", s2) // string 转 []rune(处理中文) s3 := "你好" r := []rune(s3) fmt.Printf("[]rune: %v (Unicode码点)\n", r) fmt.Printf("字符个数: %d\n", len(r)) // []rune 转 string r2 := []rune{0x4E2D, 0x6587} s4 := string(r2) fmt.Printf("string: %s\n", s4) }

3.3 strconv 包转换

import "strconv" ​ func main() { // 字符串转数值 i, _ := strconv.Atoi("42") fmt.Printf("Atoi: %d\n", i) f, _ := strconv.ParseFloat("3.14", 64) fmt.Printf("ParseFloat: %.2f\n", f) b, _ := strconv.ParseBool("true") fmt.Printf("ParseBool: %t\n", b) // 数值转字符串 s1 := strconv.Itoa(42) s2 := strconv.FormatFloat(3.14, 'f', 2, 64) s3 := strconv.FormatBool(true) fmt.Printf("Itoa: %s\n", s1) fmt.Printf("FormatFloat: %s\n", s2) fmt.Printf("FormatBool: %s\n", s3) }

四、可见性规则

Go语言使用首字母大小写来控制标识符的可见性:

package mypackage ​ import "fmt" ​ // MyPublicFunc 首字母大写,可被其他包导出 func MyPublicFunc() { fmt.Println("我是公开函数") } ​ // myPrivateFunc 首字母小写,仅限本包内使用 func myPrivateFunc() { fmt.Println("我是私有函数") } ​ // MyPublicVar 公开变量 var MyPublicVar = 100 ​ // myPrivateVar 私有变量 var myPrivateVar = 200 ​ // MyPublicType 公开结构体 type MyPublicType struct { Name string // 公开字段 age int // 私有字段 }

规则总结:

  • 首字母大写:导出标识符,可被其他包访问

  • 首字母小写:未导出标识符,仅限本包内访问

五、命名规范

5.1 变量命名

Go语言推崇简洁、有意义的命名:

// ✅ 推荐:简洁清晰 userName := "张三" isActive := true itemCount := 0 ​ // ❌ 避免:过于简短或无意义 x := "张三" // x是什么? a := 1 // a是什么? data := "" // 什么数据? ​ // ❌ 避免:中文拼音 xingming := "张三"

5.2 常量命名

// 常量组命名规范 const ( StatusOK = 200 StatusNotFound = 404 StatusError = 500 ) ​ // 枚举类型通常使用 iota const ( Monday = iota Tuesday Wednesday Thursday Friday Saturday Sunday )

5.3 包命名

// ✅ 推荐:简短、全小写、不含下划线 import ( "fmt" "strings" "os/user" ) ​ // ❌ 避免:下划线、混合大小写 // import "my_package" // 下划线不推荐 // import "MyPackage" // 混合大小写不推荐

六、代码规范检查

使用go vetgofmt保持代码规范:

# 格式化代码 go fmt ./... ​ # 检查代码问题 go vet ./... ​ # 使用 golangci-lint(需安装) golangci-lint run

总结

本文详细介绍了Go语言的变量声明、数据类型、类型转换和可见性规则。需要牢记:

  1. 变量声明var声明可带类型,:=用于函数内短声明

  2. 数据类型:数值、字符串、布尔、rune/byte

  3. 类型转换:必须显式转换,不存在隐式转换

  4. 可见性:首字母大写为导出,小写为私有

思考题:

  1. var a int = 3.14为什么不能编译通过?

  2. 如何正确判断中文字符串的长度?

  3. 为什么推荐使用 float64 而不是 float32?


📚 下一篇文章我们将深入讲解 Go 语言的运算符与控制流程,敬请期待!

http://www.jsqmd.com/news/705648/

相关文章:

  • realme 全面并入 OPPO 体系,独立商城正式关停!
  • 解锁音乐自由:ncmppGui极速NCM文件解密工具完全指南
  • Java历史—沙箱安全机制
  • CupcakeAGI:构建多模态感知与自主规划AI智能体的实践指南
  • LinkSwift:跨平台网盘直链解析引擎的技术架构与配置指南
  • 怎样高效部署ClearerVoice-Studio:专业级AI语音处理工具包全面指南
  • GraSP 深度解析:当 Skill 不再是瓶颈,编排才是
  • 如何用开源工具Driver Store Explorer高效管理Windows驱动程序存储?
  • 重构仿真工作流:从手动操作到智能自动化的范式革命
  • StabilityAI SDXL-Turbo部署案例:从HuggingFace模型加载到本地服务
  • 三指数平滑方法在时间序列预测中的应用与优化
  • Stream-rec直播流录制:从零开始构建你的自动化录播系统
  • 如何快速上手Translumo:Windows平台终极实时屏幕翻译工具完整指南
  • HotGo插件化架构实战:如何用微核设计实现高效多人协同开发
  • 保姆级避坑指南:用HuggingFace的chinese-roberta-wwm-ext做情感分析,从数据预处理到模型部署
  • RexUniNLU入门必看:为什么中文标签要带动词?‘订票意图’优于‘订票’
  • Agent游戏开发框架OpenGame
  • 突破性音乐解锁方案:一站式解决加密音频格式兼容性难题
  • PLC编程架构_西门子 S7 标准编程指南
  • 如何高效使用XJoy将Joy-Con变身手柄:完整实战指南
  • 破局“银行+电信”老路:澳洲气候科技(ClimateTech)与绿色能源的 IT 高薪人才缺口
  • LocalClaw + DeepSeek V4:本地部署百万 token 上下文实战
  • 5分钟掌握WebToEpub:将网页小说转为电子书的终极解决方案
  • 一站式解决方案:Ledger 官方授权店详细购买与服务全指南
  • WaveDrom:3分钟掌握专业数字时序图绘制的终极指南
  • python argparse
  • DeepSeek V4 Hybrid Attention Architecture 技术解析
  • Claude Code MCP 和 Skill
  • CompressO视频压缩工具:3分钟掌握免费开源的多媒体压缩神器
  • 大语言模型驱动开放世界智能体:Odyssey框架在《我的世界》中的实践