随手记录第十六话 -- Go 语言入门:基础知识与常用框架

随着 Go 语言(简称 Golang)因其高效、简洁和强大的并发能力而备受关注,越来越多的开发者开始学习这门语言。本文将带你从零开始了解 Go 的基本知识,并介绍一些常用的框架和工具。

快捷目录

一、Go 的安装与环境配置

在正式学习之前,我们需要先安装 Go 环境并进行基础配置。

1.安装 Go

访问 Go 官方网站 https://golang.org/dl/ 下载对应操作系统的安装包。

  • 对于 Windows 用户,可以选择 .msi 文件进行安装。
  • 对于 macOS 用户,可以根据电脑芯片型号下载AMD或者ARM的,也可以使用 Homebrew:
shell 复制代码
  brew install go
  • 对于 Linux 用户,可以直接下载 tar 包并解压。

2.环境

安装完成后,需要设置以下两个环境变量:

  • GOPATH:Go 项目的默认工作目录。
  • GOROOT:Go 的安装路径(一般无需手动设置)。

    环境变量需要添加GO安装目录,PAHT中添加$GOPATH/bin
    src 默认工作目录,也就是项目的根目录
    pkg下载的依赖存放目录,例如下图我的学习项目

3.验证

打开终端或命令行工具,输入以下命令检查 Go 是否安装成功:

shell 复制代码
~ > go version                                                                            node system rb 2.7.6 14:53:44
go version go1.23.3 darwin/amd64

如果看到类似上面的输出,则说明安装完成。

二、Go 的基本语法与常用命令

1.基础语法

  • Go程序的基本结构:
shell 复制代码
package main

import "fmt"

func main() {
    fmt.Printf("Hello, World!\n")
}
  • 包管理:Go 使用 import 关键字导入包,常见的标准库包括 fmt(格式化输入输出)、os(操作系统交互)等。

2.常用命令

  • go get:拉取依赖包
shell 复制代码
go get github.com/gin-gonic/gin
  • go mod tidy: 整理项目依赖,生成或者更新go.mod和go.sum文件。
shell 复制代码
go mod tidy
  • go clean: 清理工作目录中的编译文件和其他临时文件。
shell 复制代码
go clean -modcache

三、Go 的依赖管理与模块化

1. 模块初始化

在项目根目录下运行以下命令,初始化 Go 模块:

shell 复制代码
go mod init your-module-name

这会生成一个 go.mod 文件,记录项目的依赖信息。

2. 下载依赖包

使用 go get 命令下载所需的依赖包。例如:

shell 复制代码
go get -u github.com/gin-gonic/gin

如果下载不了 需要设置代理 该设置永久生效

shell 复制代码
//添加代理
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. 清理无用的依赖包

运行以下命令清理不再使用的依赖包:

shell 复制代码
go mod tidy

四、Go 的基础使用语法

1.变量声明

在 Go 中,变量声明使用 var 关键字,也可以通过简短声明 := 来简化。格式如下:

go 复制代码
// 声明一个变量并初始化
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
    示列:
go 复制代码
var a bool = true       // 布尔类型
var b int = 100         // 整数类型
var c float32 = 3.14    // 浮点类型
var d string = "Hello"  // 字符串类型

3.函数

Go 中的函数使用 func 关键字定义。格式如下:

go 复制代码
// 带返回值的函数
func add(a int, b int) int {
    return a + b
}

// 不带返回值的函数
func sayHello() {
    println("Hello, World!")
}

4.条件语句

Go 的条件语句与ifelse结构类似:

go 复制代码
age := 18

if age >= 18 {
    println("成年人")
} else {
    println("未成年人")
}

// 简化写法(可以在 if 中直接声明变量)
a := 50
if a > 30 && a < 60 { 
    println("A 在 30 到 60 之间")
}

5.循环语句

Go 的循环结构支持 forwhile(隐含在 for 中)和 range

go 复制代码
// 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.数组和切片

数组是固定长度的集合,而切片是动态的、更灵活的数组。

shell 复制代码
// 定义一个数组
arr := [3]int{1, 2, 3}

// 定义一个切片(从数组中获取)
slice := arr[0:2] // 切片包含索引 0 和 1 的元素

println(len(arr))   // 输出长度:3
println(len(slice)) // 输出长度:2

7.Map操作

go 复制代码
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 中的重要数据类型,用于封装多个字段。

go 复制代码
// 定义一个结构体
type Person struct {
    name string
    age  int
}

// 初始化结构体实例
p := Person{name: "Alice", age: 30}
println(p.name) // 输出:Alice

9.接口(Interface)

Go 的接口用于定义行为,支持动态类型。

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 类型。

go 复制代码
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 项目:

初始化模块

shell 复制代码
go mod init your-module-name

下载依赖

shell 复制代码
go get -v

构建项目

shell 复制代码
go build

运行程序

shell 复制代码
./your-program

五、Go 的并发模型

Go 的 goroutinechannel 提供了强大的并发支持。以下是一个简单的例子:

shell 复制代码
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)
}

运行后,你会看到 helloworld 交替输出。

六、常用框架介绍

1.Gin框架

Gin 是一个高性能的 HTTP Web 框架,适用于构建 API 和 Web 应用。以下是快速入门示例:
安装 Gin

shell 复制代码
go get -u github.com/gin-gonic/gin

创建一个简单的 Web 应用

在项目目录下创建 main.go 文件:

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 端口
}

运行程序

shell 复制代码
go run main.go

打开浏览器访问 http://localhost:8080/ping,你会看到响应结果。

2.引入gorm框架依赖包

官网地址 https://gorm.io/zh_CN/docs/index.html

shell 复制代码
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

shell 复制代码
go install github.com/zeromicro/go-zero/tools/goctl@latest

后续的代码生成,包括一些特殊的脚手架都是通过goctl安装

3.2 验证goctl

shell 复制代码
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 相关组件

shell 复制代码
goctl env check --install --verbose --force

如果出现安装超时的 单独执行这个指令

shell 复制代码
goctl env check --install

验证protoc

shell 复制代码
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 安装 需要在项目内安装

shell 复制代码
$ 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拉取并运行:

yaml 复制代码
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

自行选一种方式启动即可 ,基础命令

shell 复制代码
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

shell 复制代码
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修改对应的配置

yml 复制代码
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接口的响应

go 复制代码
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服务

shell 复制代码
cd user/rpc && go run user.go

postman测试rpc服务,首先需要登陆,然后在file->gRPC新建一个接口请求,引入文件 service definition - import user.proto ,然后输入下面内容进行测试

shell 复制代码
127.0.0.1:18080  /getUser
请求参数
{
    "id":"1112"
}
返回
{
    "id": "1112",
    "name": "收到ID请求:1112",
    "gender": true
}

4.2 视频服务API

新建video/api/video.api

shell 复制代码
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/

代码生成后,修改对应配置

yml 复制代码
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

go 复制代码
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修改返回结果

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服务
shell 复制代码
~/go/src/gozerodemo/user/rpc main !10 ?8 > go run user.go                                   
Starting rpc server at 0.0.0.0:18080...
  • 再启动VideoApi服务
shell 复制代码
~/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
shell 复制代码
{"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

长风破浪会有时,直挂云帆济沧海。

相关推荐
IT北辰6 分钟前
源码:用Python进行电影数据分析实战指南
开发语言·python
重生之成了二本看我逆天改命走向巅峰1 小时前
从0搭建Tomcat第二天:深入理解Servlet容器与反射机制
java·开发语言·笔记·学习·servlet·tomcat·idea
rkmhr_sef1 小时前
Java进阶:Dubbo
java·开发语言·dubbo
数维学长9861 小时前
【2025rust笔记】超详细,小白,rust基本语法
开发语言·笔记·rust
不止会JS1 小时前
cursor使用经验分享(java后端服务开发向)
java·开发语言·经验分享·cursor
徐白11771 小时前
Rust WebAssembly 入门教程
开发语言·rust·wasm
solomonzw1 小时前
C++ 学习(八)(模板,可变参数模板,模板专业化(完整模板专业化,部分模板专业化),类型 Traits,SFINAE(替换失败不是错误),)
c语言·开发语言·c++·学习
阳洞洞1 小时前
“nullptr“ should be used to denote the null pointer
开发语言·c++
牛马baby2 小时前
Java高频面试之集合-03
java·开发语言·面试
用手手打人2 小时前
多线程&JUC(二)
java·开发语言