随着 Go 语言(简称 Golang)因其高效、简洁和强大的并发能力而备受关注,越来越多的开发者开始学习这门语言。本文将带你从零开始了解 Go 的基本知识,并介绍一些常用的框架和工具。
一、Go 的安装与环境配置
在正式学习之前,我们需要先安装 Go 环境并进行基础配置。
1.安装 Go
访问 Go 官方网站 https://golang.org/dl/ 下载对应操作系统的安装包。
- 对于 Windows 用户,可以选择 .msi 文件进行安装。
- 对于 macOS 用户,可以根据电脑芯片型号下载AMD或者ARM的,也可以使用 Homebrew:
brew install go
- 对于 Linux 用户,可以直接下载 tar 包并解压。
2.环境
安装完成后,需要设置以下两个环境变量:
- GOPATH:Go 项目的默认工作目录。
- GOROOT:Go 的安装路径(一般无需手动设置)。
环境变量需要添加GO安装目录,PAHT中添加$GOPATH/bin
src
默认工作目录,也就是项目的根目录
pkg
下载的依赖存放目录,例如下图我的学习项目
3.验证
打开终端或命令行工具,输入以下命令检查 Go 是否安装成功:
~ > go version node system rb 2.7.6 14:53:44
go version go1.23.3 darwin/amd64
如果看到类似上面的输出,则说明安装完成。
二、Go 的基本语法与常用命令
1.基础语法
- Go程序的基本结构:
package main
import "fmt"
func main() {
fmt.Printf("Hello, World!\n")
}
- 包管理:Go 使用 import 关键字导入包,常见的标准库包括 fmt(格式化输入输出)、os(操作系统交互)等。
2.常用命令
- go get:拉取依赖包
go get github.com/gin-gonic/gin
- go mod tidy: 整理项目依赖,生成或者更新go.mod和go.sum文件。
go mod tidy
- go clean: 清理工作目录中的编译文件和其他临时文件。
go clean -modcache
三、Go 的依赖管理与模块化
1. 模块初始化
在项目根目录下运行以下命令,初始化 Go 模块:
go mod init your-module-name
这会生成一个 go.mod
文件,记录项目的依赖信息。
2. 下载依赖包
使用 go get 命令下载所需的依赖包。例如:
go get -u github.com/gin-gonic/gin
如果下载不了 需要设置代理 该设置永久生效
//添加代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct
#查看
go env GOPROXY
#去掉代理 改为默认
go env -w GOPROXY=direct
//七牛云的
go env -w GOPROXY=https://goproxy.cn,direct
//阿里云的
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
3. 清理无用的依赖包
运行以下命令清理不再使用的依赖包:
go mod tidy
四、Go 的基础使用语法
1.变量声明
在 Go 中,变量声明使用 var
关键字,也可以通过简短声明 :=
来简化。格式如下:
// 声明一个变量并初始化
var name string = "Alice"
var age int = 30
// 简短声明(只在函数内部使用)
name := "Bob" // 不需要指定类型,Go 会自动推断类型
age := 25 // 同上
2.基本数据类型
Go 提供了丰富的内置数据类型:
- 布尔类型:
bool
- 整数类型:
int
,uint
,byte
(8位无符号整数) - 浮点类型:
float32
,float64
- 字符串类型:
string
- 复数类型:
complex64
,complex128
示列:
var a bool = true // 布尔类型
var b int = 100 // 整数类型
var c float32 = 3.14 // 浮点类型
var d string = "Hello" // 字符串类型
3.函数
Go 中的函数使用 func
关键字定义。格式如下:
// 带返回值的函数
func add(a int, b int) int {
return a + b
}
// 不带返回值的函数
func sayHello() {
println("Hello, World!")
}
4.条件语句
Go 的条件语句与if
和else
结构类似:
age := 18
if age >= 18 {
println("成年人")
} else {
println("未成年人")
}
// 简化写法(可以在 if 中直接声明变量)
a := 50
if a > 30 && a < 60 {
println("A 在 30 到 60 之间")
}
5.循环语句
Go 的循环结构支持 for
、while
(隐含在 for 中)和 range
。
// for 循环
for i := 0; i < 5; i++ {
println(i)
}
// while 风格的循环
count := 5
for count > 0 {
println(count)
count--
}
// range 遍历数组或切片
arr := [3]int{1, 2, 3}
for index, value := range arr {
println("索引:", index, "值:", value)
}
6.数组和切片
数组是固定长度的集合,而切片是动态的、更灵活的数组。
// 定义一个数组
arr := [3]int{1, 2, 3}
// 定义一个切片(从数组中获取)
slice := arr[0:2] // 切片包含索引 0 和 1 的元素
println(len(arr)) // 输出长度:3
println(len(slice)) // 输出长度:2
7.Map操作
var a map[string]string
a = make(map[string]string)
//a = make(map[string]string,7) //指定长度
a = map[string]string{
"vvv": "1212",
"xxx": "12121",
} //预设值
a["aaa"] = "bbb"
a["ccc"] = "ddd"
fmt.Println(a)
fmt.Println(a["ccc"])
8.结构体(Struct)
结构体是 Go 中的重要数据类型,用于封装多个字段。
// 定义一个结构体
type Person struct {
name string
age int
}
// 初始化结构体实例
p := Person{name: "Alice", age: 30}
println(p.name) // 输出:Alice
9.接口(Interface)
Go 的接口用于定义行为,支持动态类型。
type Shape interface {
area() float64
}
// 实现接口的结构体
type Circle struct {
radius float64
}
func (c Circle) area() float64 {
return 3.14 * c.radius * c.radius
}
// 使用接口
var shape Shape = Circle{radius: 2}
println(shape.area()) // 输出:12.56
10.错误处理(Error)
Go 中的错误处理使用 error
类型。
func divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为零")
}
return a / b, nil
}
// 调用函数并检查错误
result, err := divide(10, 0)
if err != nil {
println(err) // 输出:除数不能为零
}
11.Go的常用命令
在终端中使用以下命令来管理 Go 项目:
初始化模块
go mod init your-module-name
下载依赖
go get -v
构建项目
go build
运行程序
./your-program
五、Go 的并发模型
Go 的 goroutine
和 channel
提供了强大的并发支持。以下是一个简单的例子:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("hello")
go say("world")
var input string
fmt.Scanln(&input)
}
运行后,你会看到 hello
和 world
交替输出。
六、常用框架介绍
1.Gin框架
Gin 是一个高性能的 HTTP Web 框架,适用于构建 API 和 Web 应用。以下是快速入门示例:
安装 Gin
go get -u github.com/gin-gonic/gin
创建一个简单的 Web 应用
在项目目录下创建 main.go
文件:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run(":8080") // 启动服务器,默认监听 8080 端口
}
运行程序
go run main.go
打开浏览器访问 http://localhost:8080/ping
,你会看到响应结果。
2.引入gorm框架依赖包
官网地址 https://gorm.io/zh_CN/docs/index.html
go get -u gorm.io/gorm
#go get -u gorm.io/driver/sqlite
go get -u gorm.io/driver/mysql #这里用的是mysql
测试代码,从gorm官网获取这里就不贴了
3.go-zero框架(微服务框架)
官方网站 https://go-zero.dev/docs/tasks
3.1 安装goctl
go install github.com/zeromicro/go-zero/tools/goctl@latest
后续的代码生成,包括一些特殊的脚手架都是通过goctl
安装
3.2 验证goctl
goctl --version
#如果验证不通过 需添加到path
# 如果使用 bash
vim ~/.bash_profile
# 或者如果使用 zsh
vim ~/.zshrc
export PATH=$PATH:/Users/admin/go/bin
3.3 安装protoc,通过 goctl 可以一键安装 protoc,protoc-gen-go,protoc-gen-go-grpc 相关组件
goctl env check --install --verbose --force
如果出现安装超时的 单独执行这个指令
goctl env check --install
验证protoc
goctl env check --verbose
[goctl-env]: "protoc" is already installed in "/Users/admin/go/bin/protoc"
[goctl-env]: looking up "protoc-gen-go"
[goctl-env]: "protoc-gen-go" is installed
[goctl-env]: looking up "protoc-gen-go-grpc"
[goctl-env]: "protoc-gen-go-grpc" is installed
[goctl-env]: congratulations! your goctl environment is ready!
3.4 go-zero 安装 需要在项目内安装
$ mkdir <project name> && cd <project name> # project name 为具体值
$ go mod init <module name> # module name 为具体值
$ go get -u github.com/zeromicro/go-zero@latest
如拉取不下来,建议按照上面三-2
说的方法设置代理
3.5 etcd 微服务配置中心 服务发现
官网:https://etcd.io/
etcd 是一个强一致的分布式键值存储,它 提供了一种可靠的方法来存储需要由 分布式系统或计算机集群。它优雅地处理领导者 在网络分区期间进行选举,甚至可以容忍机器故障 在领导节点中。 了解更多信息
这里使用的是docker拉取并运行:
docker pull bitnami/etcd:3.5
docker run --name etcd01 -d -p 2379:2379 -p 2300:2300 -e ALLOW_NONE_AUTHENTICATION=YES bitnami/etcd:3.5
version: '3'
services:
etcd01:
image: bitnami/etcd:3.5
container_name: etcd01
ports:
- 2379:2379
- 2300:2300
environment:
- ALLOW_NONE_AUTHENTICATION=YES
networks:
- my-net
networks:
my-net:
external: true
自行选一种方式启动即可 ,基础命令
etcdctl put 111 222
etcdctl get 111
etcdctl get --prefix 111_
etcdctl del 111
etcdctl watch 111
4.go-zero服务创建测试
用户服务提供RPC接,通过用户ID获取用户信息,视频服务提供Http接口调用用户的RPC服务
4.1 用户服务rpc
新建user/rpc/user.proto
syntax = "proto3"; //这个必须要加 否则默认用2版本 需要带 "required", "optional", or "repeated"三个前置
option go_package = "./user";
message IdRequest {
string id = 1;
}
message UserResponse{
string id = 1;
string name = 2;
bool gender = 3;
}
service User{
rpc getUser(IdRequest) returns (UserResponse);
}
//通过proto生成目录及代码
//goctl rpc protoc user/rpc/user.proto --go_out=user/rpc/types --go-grpc_out=user/rpc/types --zrpc_out=user/rpc/
生成对应代码后,找到user/rpc/etc/user.yaml
修改对应的配置
Name: user.rpc
ListenOn: 0.0.0.0:18080
Etcd:
Hosts:
- 192.168.168.131:2379 #etcd的地址
Key: user.rpc
然后在user/rpc/internal/logic/getuserlogic.go
修改rpc接口的响应
func (l *GetUserLogic) GetUser(in *user.IdRequest) (*user.UserResponse, error) {
// todo: add your logic here and delete this line
return &user.UserResponse{
Id: in.GetId(),
Name: "收到ID请求:" + in.GetId(),
Gender: true,
}, nil
}
然后在对应目录下启动rpc服务
cd user/rpc && go run user.go
postman测试rpc服务,首先需要登陆,然后在file->gRPC
新建一个接口请求,引入文件 service definition - import user.proto
,然后输入下面内容进行测试
127.0.0.1:18080 /getUser
请求参数
{
"id":"1112"
}
返回
{
"id": "1112",
"name": "收到ID请求:1112",
"gender": true
}
4.2 视频服务API
新建video/api/video.api
type (
VideoReq {
//path表示为路径参数 form:"id" form参数 header:"client_id" 头部参数
//form:"scope,optional" form参数可选 默认是必传
Id string `path:"id"`
}
VideoRes {
Id string `json:"id"`
Name string `json:"name"`
}
LoginReq {
Username string `json:"username"`
Password string `json:"password"`
}
)
@server (
prefix: /api/videos //结果前缀
)
service video {
//@doc(
// summary: "根据ID获取视频用户信息"
//)
@handler getVideo
get /:id (VideoReq) returns (VideoRes)
//get /api/videos/:id (VideoReq) returns (VideoRes)
}
//通过proto生成代码
//goctl api go -api video/api/video.api -dir video/api/
代码生成后,修改对应配置
Name: video
Host: 0.0.0.0
Port: 18888
UserRpc:
Etcd:
Hosts:
- 192.168.168.131:2379 #etcd的地址
Key: user.rpc
本服务使用了UserRpc 需要在video/api/internal/svc/ServiceContext
配置UserRpc
type ServiceContext struct {
Config config.Config
UserRpc userclient.User //这个需要已经有依赖包存在
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
//配置UserRpc
UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
}
}
在video/api/internal/logic/getvideologic.go
修改返回结果
func (l *GetVideoLogic) GetVideo(req *types.VideoReq) (resp *types.VideoRes, err error) {
//调用RPC服务
user1, err := l.svcCtx.UserRpc.GetUser(l.ctx, &user.IdRequest{
Id: req.Id,
})
if err != nil {
return nil, err
}
return &types.VideoRes{
Id: user1.GetId(),
Name: user1.GetName(),
}, nil
}
4.3 测试
- 先启动UserRpc服务
~/go/src/gozerodemo/user/rpc main !10 ?8 > go run user.go
Starting rpc server at 0.0.0.0:18080...
- 再启动VideoApi服务
~/go/src/gozerodemo/video/api main !10 ?8 > go run video.go
Starting server at 0.0.0.0:18888...
- 请求
http://127.0.0.1:18888/api/videos/1234
{"id":"1234","name":"收到ID请求:1234"}
七、Go 的开发工具
1. GoLand
JetBrains 提供的 Go 集成开发环境(IDE),支持代码补全、调试和版本控制等功能。
2. VS Code + Go 扩展
如果你更喜欢轻量级编辑器,可以使用 Visual Studio Code 并安装 Go 插件来增强开发体验。
八、总结
通过本文的介绍,你已经了解了 Go 的基本语法、常用命令以及一些流行的框架。接下来,各位彦祖可以尝试以下内容:
深入学习 Gin 或 Go-zero 框架,构建一个完整的 Web 应用。
探索 Go 的并发模型和内存管理机制。
参与开源项目,提升自己的实战能力。
以上就是本文的全部内容了,希望以上内容对您有所帮助!
上一篇:随手记录第十五话 – Spring Boot 3.2.3+Grafana+Prometheus+Loki实现一套轻量级监控加日志收集系统
下一篇:随手记录第十七话 – xxxx
长风破浪会有时,直挂云帆济沧海。