1. Go语言基础:从零开始,搭建你的第一个Go程序

大家好,欢迎来到《Go与Kubernetes云原生实践》的第一章。

说实话,我接触Go语言已经有七八年了。记得最早是在一个微服务重构项目里,团队被Java的GC折腾得够呛,才决定试试Go。结果这一试,就再也没回头。今天咱们就从最基础的东西聊起,把Go的来龙去脉、环境搭建、还有第一个程序跑通。

1.1 Go语言发展史:为什么会有这门语言?

Go语言诞生于2007年的Google。当时Google内部的基础设施已经非常庞大,C++编译慢得像蜗牛,Java又太重,Python在并发场景下力不从心。于是三位大佬——Robert Griesemer、Rob Pike、Ken Thompson(对,就是Unix和C语言的那位Ken Thompson)——决定自己造个轮子。

2009年,Go正式对外开源。2012年,Go 1.0发布,承诺向后兼容。这个承诺一直保持到今天,你想想看,这在编程语言界有多难得。

我个人觉得,Go之所以能火,核心就三点:

  • 编译快:大型项目几秒搞定,C++项目喝杯咖啡还没编译完
  • 并发简单:goroutine和channel,比线程池好用一百倍
  • 部署方便:编译成单个二进制文件,扔到服务器就能跑

我在项目中遇到过最爽的一次,是把一个Java微服务用Go重写,内存占用从2GB降到了200MB,编译时间从5分钟变成了3秒。嗯,当时团队都惊呆了。

1.2 Go核心特性:凭什么选它?

咱们不整那些虚的,直接说干货。

1.2.1 静态类型 + 类型推断

Go是静态类型语言,变量类型在编译时就确定了。但它又支持类型推断,写起来像动态语言一样爽。

// 显式声明
var name string = "Go语言"

// 类型推断(我更喜欢这种写法)
age := 12

1.2.2 并发原语:goroutine和channel

这是Go最核心的卖点。goroutine是轻量级线程,一个Go程序可以轻松启动几十万个goroutine。channel则是goroutine之间通信的管道。

// 启动一个goroutine
go func() {
    fmt.Println("我在goroutine里运行")
}()

// 用channel传递数据
ch := make(chan string)
go func() {
    ch <- "hello"
}()
msg := <-ch

我曾经用Go写过一个消息推送服务,单机扛住了100万并发连接。换成Java的话,光线程栈内存就得吃掉好几个GB。

1.2.3 垃圾回收

Go有GC,但它的GC延迟极低。Go 1.5之后引入了并发GC,STW(Stop The World)时间控制在毫秒级别。说白了,你不用担心内存泄漏,也不用像C++那样手动管理内存。

1.2.4 标准库强大

Go的标准库涵盖了HTTP服务器、JSON解析、加密、压缩、数据库驱动等常用功能。很多场景下,你不需要引入任何第三方库。

核心总结:Go的设计哲学就是「少即是多」。它没有继承、没有泛型(1.18之前)、没有异常机制。但正是这种克制,让Go代码极其易读、易维护。

1.3 安装Go与GOPATH/GOMODULE配置

这部分我踩过不少坑,咱们一步步来。

1.3.1 安装Go

https://go.dev/dl/ 下载对应操作系统的安装包。Windows用户直接点msi,Mac用户点pkg,Linux用户下载tar.gz。

安装完成后,打开终端验证:

go version
# 输出类似:go version go1.21.0 linux/amd64

1.3.2 GOPATH模式(老古董了,但得知道)

在Go 1.11之前,所有Go项目都必须放在 $GOPATH/src 目录下。这个设计很蛋疼,我刚开始学的时候就因为路径问题折腾了半天。

# 设置GOPATH(默认在 ~/go)
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

# 项目必须放在这里
mkdir -p $GOPATH/src/github.com/yourname/myproject

避坑指南:千万不要把GOPATH设置成你的项目目录!我曾经这么干过,结果go get命令把依赖下载到了项目里,搞得一团糟。

1.3.3 Go Module模式(现代标准)

从Go 1.11开始,官方推出了Go Module。现在所有新项目都应该用这个模式。

# 初始化一个新模块
mkdir myproject
cd myproject
go mod init myproject

# 这会生成一个 go.mod 文件
# 内容类似:
# module myproject
# go 1.21

我个人习惯,所有项目都从 go mod init 开始。它解决了依赖版本管理的痛点,再也不用担心「在我电脑上能跑」的问题了。

特性 GOPATH模式 Go Module模式
项目位置 必须在GOPATH/src下 任意位置
依赖管理 手动或第三方工具 go.mod自动管理
版本控制 支持语义化版本
推荐度 ❌ 不推荐 ✅ 强烈推荐

1.4 第一个Go程序:Hello, World!

终于到写代码的环节了。咱们写一个经典的Hello World,但我会加点料。

// main.go
package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Println("Hello, Go语言!")
    fmt.Printf("我运行在 %s 架构上\n", runtime.GOARCH)
    fmt.Printf("Go版本: %s\n", runtime.Version())
}

运行方式:

# 直接运行
go run main.go

# 或者编译成二进制再运行
go build -o hello main.go
./hello

输出结果:

Hello, Go语言!
我运行在 amd64 架构上
Go版本: go1.21.0

小技巧go run 适合开发调试,go build 适合生产部署。编译出来的二进制文件可以直接扔到任何同架构的Linux服务器上跑,不需要安装Go运行时。这就是Go的「静态编译」特性。

嗯,到这里,你的Go环境就搭好了,第一个程序也跑通了。是不是很简单?

下一章咱们会深入Go的语法细节,包括变量、常量、控制流、函数等。我会结合自己在实际项目中的踩坑经历,帮你避开那些新手常见的问题。

记住:学Go,别着急。先把环境搞利索,后面的事情就水到渠成了。


公众号:蓝海资料掘金营,微信deep3321