ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Go 变量声明四问四答:var 语法、先声明后使用、强类型与命名规则(learngo 实战详解)

Go 变量声明四问四答:var 语法、先声明后使用、强类型与命名规则(learngo 实战详解) 示例工程教程【免费下载链接】learngo❤️ 1000 Hand-Crafted Go Examples, Exercises, and Quizzes. Learn Go by fixing 1000 tiny programs.项目地址https://gitcode.com/gh_mirrors/le/learngo点击查看免费下载本文以 learngo 仓库中 06-variables/02-declarations/questions/02-declaration/README.md 的四道选择题为骨架结合仓库内数十个可运行示例源码系统讲解 Go 变量声明的语法、必须先声明后使用的编译期规则、Go 的强类型特性以及变量命名规范并延伸到零值、空白标识符与多重声明等进阶话题。读完本文你将能独立判断一段 Go 代码中变量声明是否合法、为何报错以及如何写出符合 Go 惯例的声明代码。一、声明变量的正确语句var关键字的完整语法quiz 第一题给出四个候选语句要求选出声明变量的正确写法* name int * vars string name * var name integer * var width int *CORRECT*Go 语言声明变量的关键字是var其基本语法结构为var 变量名 类型即关键字var 变量名 类型类型写在变量名的后面而不是像 C/Java 那样写在前面。这是 Go 与许多主流语言最直观的差异之一。仓库中 06-variables/02-declarations/01-declaration-syntax/01-syntax/main.go 给出了最精简的演示package main import fmt func main() { var speed int fmt.Println(speed) }var speed int声明了一个名为speed、类型为int的变量随后可以直接用fmt.Println打印它。对照四个候选答案逐一分析错误原因name int—— 缺少var关键字Go 编译器会报expected declaration, found name之类的错误vars string name—— 关键字拼写错误没有vars且类型与变量名的顺序也不对var name integer—— 类型名错误Go 的内置整数类型是int不存在integer关键字。四种基本类型的声明示例quiz 只考察了int一种类型但仓库在 06-variables/02-declarations/02-example-declarations/ 下为 Go 的四种基本类型各准备了一个可运行示例01-int、02-float64、03-bool、04-string。例如 02-example-declarations/01-int/main.go 声明了nFiles、counter、nCPU三个int变量而 02-example-declarations/04-string/main.go 声明了msg、name、text三个string变量func main() { var msg string var name string var text string fmt.Println(msg, name, text) }把四类声明放在一起看语法完全一致只是类型名不同var age int // 整数 var ratio float64 // 浮点数 var isOK bool // 布尔 var brand string // 字符串这正对应仓库 06-variables/02-declarations/03-zero-values/main.go 中的写法也与 06-variables/01-basic-data-types/main.go 中关于基本数据类型的讲解一脉相承。二、先声明后使用Go 的编译期强制规则quiz 第二题* You can use a variable before declaring it * You have to declare a variable before using it *CORRECT*Go 规定变量必须先声明后使用。这是编译器层面的强制规则违反它会在编译阶段直接报错程序无法运行。仓库 06-variables/02-declarations/01-declaration-syntax/03-order-of-declaration/main.go 专门演示了这一规则package main func main() { // fmt.Println(speed) // var speed int }注意上面两行都被注释掉了如果先写fmt.Println(speed)再写var speed int也就是在声明之前就尝试使用speedGo 编译器会报undefined: speed错误。正确的顺序只能是先声明、后使用package main import fmt func main() { var speed int // 1. 先声明 fmt.Println(speed) // 2. 后使用 }这套规则与后续章节中函数作用域、包作用域的知识见 03-packages-and-scopes/02-scopes/也紧密相关编译器需要先看到声明才知道该名字的类型与作用范围之后才能对使用处进行类型检查。从源码结构看learngo 刻意把先声明后使用放在声明语法教学的最前面就是为了让初学者从一开始就建立正确的顺序直觉。附带规则声明了却没用也会报错与先声明后使用配套的另一条规则是声明了但从未使用的变量同样会报编译错误。仓库 06-variables/02-declarations/04-unused-variables-and-blank-identifier/01-unused-variable/main.go 中对此有清晰的注释说明func main() { // unused variable error // var speed int // if you use it, the error will be gone // fmt.Println(speed) }一旦声明了var speed int却从不使用Go 编译时就会报speed declared and not used。此时有两种解决办法要么真正使用它要么把它赋给空白标识符blank identifier_见 04-unused-variables-and-blank-identifier/02-blank-identifier/main.govar speed int // 把变量交给空白标识符Go 编译器就不再抱怨 _ speed需要特别说明的是这条未使用即报错的规则只针对局部变量。同一个文件里包级变量var packageLevelVar string即使从不被使用也不会报错——仓库源码中特别注释了theres no warning for package-level vars。这是初学者最容易踩的坑之一quiz 对应的完整练习见 06-variables/02-declarations/exercises/09-unused 与10-package-variable。三、Go 是强类型语言类型是声明不可分割的一部分quiz 第三题* Weakly-Typed * Dynamically-Typed * Strongly-Typed *CORRECT* * Freely-TypedGo 是一门强类型Strongly-Typed语言。这体现在两个层面每个变量在声明时就必须有确定的类型如var speed int编译器会一直记住这个类型不同类型的值不能直接互相赋值或混用否则编译报错。仓库在 06-variables/05-type-conversion/ 中有专门章节讲解类型转换例如把一个int变量赋给float64变量必须先显式转换float64(speed)而不是像弱类型语言那样隐式进行。var speed int var ratio float64 // 错误cannot use speed (variable of type int) as float64 value // ratio speed // 正确必须先显式转换 ratio float64(speed)强类型的好处是让编译器在运行前就能拦截大量类型错误这也是 Go 代码在大型工程中易于维护、重构安全的重要原因。learngo 课程在 09-go-type-system/ 中还进一步展开了预定义类型、定义类型与底层类型的完整类型体系。四、变量命名规则什么名字是合法的quiz 第四题* int * four *CORRECT* * 2computers * one?there逐个分析四个候选名字为什么对或错候选名是否合法原因int✗int是 Go 的预定义关键字/内置类型名不能用作变量名声明var int int会报语法错误four✓由小写字母组成不是关键字完全合法2computers✗不能以数字开头标识符必须以字母或下划线开头one?there✗包含非法字符?标识符只能由字母、数字和下划线组成仓库 06-variables/02-declarations/01-declaration-syntax/02-naming-rules/main.go 用一个完整的示例展示了合法与合法的边界func main() { // CORRECT DECLARATIONS var speed int var SpeeD int // 大小写敏感这也是合法名字 // underscore is allowed but not recommended var _speed int // 下划线开头合法但不推荐 // Unicode letters are allowed var 速度 int // Unicode 字母同样允许 // keep the compiler happy _, _, _, _ speed, SpeeD, _speed, 速度 }从这段源码可以总结出 Go 命名规则的核心事实大小写敏感speed与SpeeD是两个不同的变量允许下划线开头_speed但惯例上不推荐允许 Unicode 字母如中文变量名速度也是合法标识符Go 源码默认按 UTF-8 处理这一点在仓库 19-strings-runes-bytes/ 的字符串与 rune 章节有更深入的背景该示例末尾用_, _, _, _ speed, SpeeD, _speed, 速度把四个变量一并赋给空白标识符只是为了哄编译器开心——避免触发上文提到的未使用变量编译错误。五、进阶零值、并行声明与多重声明在掌握 quiz 的四个核心答案后仓库 06-variables/02-declarations/ 还给出了三条必须了解的自然延伸。1. 声明即初始化零值机制var speed int声明出的变量不需要手动初始化就拥有确定的值——零值zero value。仓库 03-zero-values/main.go 展示了四类基本类型的零值var speed int // 零值: 0 var heat float64 // 零值: 0 var off bool // 零值: false var brand string // 零值: 空字符串 fmt.Println(speed) fmt.Println(heat) fmt.Println(off) fmt.Printf(%q\n, brand) // %q 会把空字符串显示为 也就是说即便你不写初始化表达式变量也绝不会处于未定义状态这是 Go 减少运行时错误的重要设计。2. 并行声明一行声明多个同类型变量05-multiple-declarations/02-parallel/main.go 演示了并行声明// 这一行等同于两条 var 声明 // var speed int // var velocity int var speed, velocity int fmt.Println(speed, velocity)语法要点是多个变量名用逗号分隔类型写在最后一个名字之后表示这些变量全部属于同一个类型。3. 分组声明var 块05-multiple-declarations/01-multiple/main.go 展示了把多条声明组织进一个var (...)块让代码更紧凑易读var ( speed int heat float64 off bool brand string ) fmt.Println(speed) fmt.Println(heat) fmt.Println(off) fmt.Printf(%q\n, brand)块内每条声明仍是独立的var 变量名 类型只是省略了重复的var关键字。六、用练习检验所学仓库内配套的 11 道实战题目quiz 之外learngo 为变量声明准备了 11 道循序渐进的实战练习全部集中在 06-variables/02-declarations/exercises/每题目录下都有main.go题目文件和solution/main.go参考答案Declare int—— 声明并打印一个int变量Declare bool—— 声明并打印布尔变量Declare float64—— 声明浮点变量Declare string—— 声明字符串变量Declare undeclarables—— 尝试声明非法类型名体会编译错误Declare with bits—— 使用int8、int64等位宽整数类型Declare multiple与Declare multiple 2—— 练习分组声明与并行声明Declare an unused variable—— 制造一个未使用变量编译错误再修复它Declare a package variable—— 在main函数之外声明包级变量Use before declare—— 故意在声明前使用变量观察编译器的报错信息。推荐的验证方式在仓库根目录下对某个练习执行go run 06-variables/02-declarations/exercises/01-int/main.go或先运行go vet ./...做静态检查即可复现本文讨论的各类编译错误与正确输出。仓库根目录的 go.mod 保证了这些示例可以直接以标准 Go 工具链运行。小结把四道题的答案还原成四条铁律回到 06-variables/02-declarations/questions/02-declaration/README.md 的四道选择题可以用四条铁律收束全文声明语法var 变量名 类型类型在名字之后关键字是var使用顺序先声明、后使用声明了不用局部变量同样报错可用空白标识符_兜底语言特性Go 是强类型语言类型一旦声明便不可变类型不匹配必须显式转换命名规则不能以数字开头、不能含非法字符、不能使用关键字/预定义类型名但大小写敏感且允许 Unicode 字母。这四条规则共同构成了 Go 变量体系的基石也是后续短变量声明:、赋值、类型转换乃至项目实战如 06-variables/06-project-greeter/所有内容的前提。赞分享示例工程教程【免费下载链接】learngo❤️ 1000 Hand-Crafted Go Examples, Exercises, and Quizzes. Learn Go by fixing 1000 tiny programs.项目地址https://gitcode.com/gh_mirrors/le/learngo点击查看免费下载相关推荐变量声明最佳实践DreamBerd四类型声明应用场景变量声明最佳实践DreamBerd四类型声明应用场景 在编程中变量声明看似简单实则暗藏玄机。错误的声明方式可能导致数据意外修改、内存泄漏或逻辑混乱。DreRome noVar 规则详解禁止使用 var用块级作用域声明变量Rome noVar 规则详解禁止使用 var 用块级作用域声明变量 导读 noVar 是 Rome 内置的 lint 规则自 v11.0.0 起提供属开发工具CLILint格式化静态分析代码质量构建工具Terminal.Gui 编码规范显式类型声明与 var 使用规则全解析Terminal.Gui 编码规范显式类型声明与 var 使用规则全解析 本篇技术指南围绕 Terminal.Gui.NET 跨平台终端 UI 工具包仓库UI组件跨平台桌面应用上一篇5分钟掌握ApkProtectAndroid应用安全终极防护指南下一篇B站视频永久保存终极指南5秒完成m4s到mp4的完美转换创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表