第01回 转生到了只用 Golang 的世界
我揉了揉眼睛,发现自己站在一个明亮的编程大厅,周围全是敲键盘的声音。昨天还在熬夜调试 C++ 的内存泄漏,今天却穿越到了一个奇怪的世界——这里每个人都在用一种叫 Golang 的语言编程,连路边的广告牌上都写着 “用 Golang 改变世界”。
“新来的,写个程序试试吧,”一个戴眼镜的导师走过来,递给我一台电脑,“先写个函数,打印‘Hello, World!’。”
好吧,我是 C++ 老手,这应该简单。我习惯性地写:
#include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
return 0;
}
编译器报错,提示“未知命令 #include”。我愣住了,这里没有 C++?导师冷冷地说:“这里只有 Golang,C++ 在这个世界已经消失了。”
我只好硬着头皮改成 Golang 风格,回忆着写:
package main
import "fmt"
func main()
{
fmt.Println("Hello, World!");
}
编译又报错:“expected declaration, found '{'”。我抓狂了,C++ 里函数的左花括号 {
可以换行写啊!导师叹气说:“Golang 强制要求左花括号必须和函数名在同一行,不然编译器不认。”
我改成:
func main() {
fmt.Println("Hello, World!");
}
这次编译通过了,但导师皱眉:“你干嘛加分号?Golang 语句末尾不用分号,C++ 的习惯害了你。”我尴尬地发现,C++ 里每个语句后面都要加 ;
,但这里多余的分号虽然不报错,却显得很奇怪。
我决定查查 Golang 和 C++ 的区别,打开这个世界的搜索引擎,输入“Golang vs C++”。结果显示,Golang 的语法更简洁,函数定义必须 {
同行,分号自动处理。我记下了:Golang 强制 {
同行,末尾不用 ;
。
接下来,我试着导入包。C++ 用 #include
,Golang 用 import
,我写:
import "fmt"
import "os"
导师又摇头:“可以,但最好用括号包裹,写成:
import (
"fmt"
"os"
)
这样更整齐。”我点点头,感觉 Golang 有点像在强迫我改掉 C++ 的坏习惯。
然后,我要定义变量。C++ 里我写 int a = 5;
,Golang 呢?我先试试 var a int = 5
,编译通过。但导师说:“函数里用 a := 5
更好,自动推导类型。”我试了,确实简洁,但总觉得少了点 C++ 里明确类型的安全感。
我好奇 a
的类型是什么,C++ 里用 typeid(a).name()
,Golang 怎么查?导师教我用 fmt.Fprintf(os.Stdout, "%T", a)
,比如:
a := 5
fmt.Fprintf(os.Stdout, "Type of a is %T\n", a) // 输出 "Type of a is int"
这比 C++ 的方式更直观,我记住了。
定义多个变量时,我习惯 C++ 的 int a, b;
,Golang 呢?我写 var a, b int
,单行可以;也可以多行:
var (
a int
b int
)
我试了试,感觉灵活,但一开始老是忘了一行定义多个变量的语法。
最后,导师让我定义枚举。C++ 里我用 enum Color { Red, Green, Blue };
,Golang 没有 enum
,怎么办?导师说用 const
和 iota
,比如:
const (
Red = iota // 0
Green // 1
Blue // 2
)
iota
自动递增,我觉得很聪明,但也觉得比 C++ 的 enum
抽象,适应起来费劲。
就这样,第一天在 Golang 世界,我犯了无数错,但也学到了不少。C++ 的习惯让我处处碰壁,但这个世界逼着我改变,我决定继续探索。
调查笔记:转生成为 Golang 工程师的第一回详解
本文旨在以轻小说风格的第一人称叙述,总结我在学习 Golang 的第一回,重点涵盖以下知识点:函数左花括号与函数名同行、语句末尾无需分号、用括号包裹导入包、在函数内优先用 :=
定义变量、查询变量类型、单行和多行定义多个变量、用 const
和 iota
定义枚举类型。以下为详细分析和背景信息,适合有 C++ 背景的初学者深入理解。
故事背景与情节设计
故事设定在一个以 Golang 为主流语言的世界,我作为一名 C++ 程序员“转生”到此,面临学习 Golang 的挑战。第一回的剧情围绕我在编程大厅中完成导师布置的任务,逐步掌握 Golang 的基础语法。
知识点详解
-
函数左花括号必须与函数名同行
在 C++ 中,函数的左花括号{
可以放在下一行(K&R 风格)或同一行(Allman 风格),但 Golang 强制要求{
与函数名在同一行。这是 Golang 格式化工具gofmt
的规范,违反此规则会导致编译错误。例如:func helloWorld() { // 正确 fmt.Println("Hello, World!") } func helloWorld() // 错误,{ 必须同行 { fmt.Println("Hello, World!") }
这与 C++ 的灵活性不同,旨在统一代码风格,减少歧义。对于有 C++ 背景的我来说,这是个不小的适应挑战,总是想把
{
放下一行,结果编译老是报错。 -
语句末尾无需分号
C++ 要求每条语句以分号结尾,而 Golang 自动在行尾插入分号(基于语法规则),因此通常无需手动添加分号。例如:fmt.Println("Hello, World!") // 正确,无需分号 fmt.Println("Hello, World!"); // 也可,但不推荐,增加冗余
这简化了代码编写,但需要注意,如果在一行写多条语句,则用分号分隔。来自 C++ 的我,习惯了每个语句后面加
;
,一开始老是多加,结果发现 Golang 编译器并不强制,但导师建议省略,省得代码看起来杂乱。 -
导入的包可以用括号包裹
Golang 的导入语句支持用括号包裹多个包,增强可读性,尤其在导入多个包时。例如:import ( "fmt" "os" )
与 C++ 的
#include <iostream>
不同,Golang 的导入是模块化的,括号方式更适合组织复杂的依赖。我一开始没注意,直接写import "fmt"
,后来看到别人用括号包裹,觉得更整齐,试着用了,确实方便。 -
使用
var
定义变量,但在函数内更推荐:=
Golang 提供var
关键字定义变量,类似于 C++ 的int a;
,例如:var a int = 5
但在函数内部,推荐使用短声明
:=
,它会自动推导类型,简化代码。例如:func main() { a := 5 // 自动推导为 int b := "hello" // 自动推导为 string }
:=
只能在函数内使用,var
则适用于全局变量或需要明确类型的场景。来自 C++ 的我,习惯了明确写类型,比如int a = 5;
,一开始用var a int = 5
觉得安全,但导师说函数里用a := 5
更简洁,我试了试,确实省事,但总觉得少了点“控制感”。 -
如何查询变量类型
C++ 中可以用typeid(a).name()
获取变量类型,Golang 没有直接的等价方法,但可以通过fmt.Fprintf
和%T
格式化输出类型。例如:import "fmt" import "os" func main() { a := 5 fmt.Fprintf(os.Stdout, "Type of a is %T\n", a) // 输出 "Type of a is int" }
或者使用
reflect.TypeOf
获取更详细的类型信息,但对于初学者,%T
更直观。我一开始不知道怎么查类型,导师提示用fmt.Fprintf
,试了试,觉得挺实用,尤其调试时能快速确认类型。 -
分别用单行和多行的方式定义多个变量
Golang 支持单行和多行定义多个变量,灵活性高。例如:-
单行方式:
var a, b int = 1, 2 // 明确类型 c, d := 3, 4 // 函数内,自动推导
-
多行方式:
var ( a int b int )
或:
var a int var b int
这与 C++ 的
int a, b;
类似,但 Golang 的多行方式更适合复杂场景。我一开始老是写成var a int; var b int;
,导师说可以省略分号,还可以多行写,试了试,觉得多行写更清晰,但单行写也挺快。
-
-
使用
const
定义枚举类型,以及iota
的用法
C++ 中用enum
定义枚举,Golang 没有直接的enum
,但可以用const
和iota
实现类似功能。iota
是 Golang 的常量计数器,从 0 开始自动递增。例如:const ( Red = iota // 0 Green // 1 Blue // 2 )
这与 C++ 的
enum Color { Red, Green, Blue };
功能类似,但iota
更灵活,可以跳过值或自定义。例如:const ( Sunday = iota Monday Tuesday _ // 跳过 3 Thursday // 从 4 开始 )
我一开始用 C++ 的思维想写
enum
,结果发现 Golang 没有,直接用const
和iota
,觉得挺新奇,但也觉得比enum
抽象了点,适应起来有点费劲。
对比与适应
对于有 C++ 背景的读者,这些差异可能需要时间适应。例如,函数花括号的强制同行规范可能让习惯 K&R 风格的程序员感到不适,而 :=
的引入则简化了函数内变量声明。iota
的使用则提供了一种优雅的枚举定义方式,减少了手动赋值的麻烦。
总结与展望
通过第一回的学习,我初步掌握了 Golang 的基础语法,包括函数定义、变量声明和常量枚举。这些知识点为后续深入学习并发、接口等高级特性奠定了基础。下一回,我将探索更多 Golang 的独特设计,期待更多惊喜!