Golang


Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。
Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。 对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。

除了OOP外,近年出现了一些小众的编程哲学,Go语言对这些思想亦有所吸收。例如,Go语言接受了函数式编程的一些想法,支持匿名函数与闭包。再如,Go语言接受了以Erlang语言为代表的面向消息编程思想,支持goroutine和通道,并推荐使用消息而不是共享内存来进行并发编程。总体来说,Go语言是一个非常现代化的语言,精小但非常强大。

Go

  • Go 语言最主要的特性
    自动垃圾回收 更丰富的内置类型 函数多返回值 错误处理 匿名函数和闭包 类型和接口 并发编程 反射 语言交互性
    https://www.runoob.com/go/go-tutorial.html
  • Go 和 Java 有很多共同之处
    C 系列 (强类型,括号) 静态类型 垃圾收集 内存安全 (nil 引用,运行时边界检查) 变量总是初始化 (zero/nil/false)
    方法 接口 类型断言 (实例) 反射
  • Go 与 Java 的不同之处
    代码程序直接编译成机器码,没有 VM
    静态链接二进制 内存布局控制 函数值和词法闭包 内置字符串 (UTF-8) 内置泛型映射和数组/片段 内置并发
  • Go 特意去掉了大量的特性
    没有类 没有构造器 没有继承 没有 final 没有异常 没有注解 没有自定义泛型
  • 为 Java 程序员准备的 Go 语言入门 PPT https://www.runoob.com/w3cnote/go-for-java-programmers.html

Go 项目构建

  • Module:是 Go 语言用于管理项目依赖和版本的一种机制。go.mod 文件定义了模块的元数据和依赖关系。
    go.mod 文件是声明依赖的地方,记录了项目的依赖关系。如果项目中没有 go.mod,需要先运行 go mod init 来初始化模块。然后使用 go get(或其他命令)来引入依赖,下载到本地缓存(~/go/pkg/mod),并更新 go.mod,添加对应的模块路径和版本要求。
  • Makefile:是一个用于自动化构建、测试和其他任务的工具。它允许你定义复杂的构建流程和依赖关系。
    Makefile 可以包含多个targets,例如 build、test、clean 等。make 命令会查找当前目录下的 Makefile 并执行指定的目标。
    构建过程本身不负责引入依赖,它假定所有必要的依赖已经通过 go.mod 文件声明并被解析(否则报错),将编译代码并链接所有必要的依赖来生成最终的可执行文件或库文件。如果 go.mod 中声明的依赖尚未下载,Go 工具链会自动为你下载这些依赖。如果你的项目中没有 go.mod,go build 将无法正确识别和下载依赖(除非是 Go 1.11 前的版本)
  • 项目构建…
    • 对于一个带有 go.mod 文件的 Go 项目,项目所需的依赖不会自动下载到本地环境中。需要手动运行 go mod downloadgo mod tidy 来下载依赖,或者直接运行 go build 以触发依赖的下载。
    • 如果本地已有的依赖版本与 go.mod 文件中声明的版本不同,Go 工具链会优先使用 go.mod 文件中指定的版本。Go 会从远程仓库下载与 go.mod 兼容的依赖版本,并将其存储在本地缓存目录(通常是 ~/go/pkg/mod)中。
    • Go 项目使用的依赖是项目特定的,存储在项目的本地缓存中,而不是全局的 GOPATH 或者 GOROOT 目录。这意味着不同的项目可以依赖同一库的不同版本,而不会发生冲突。其实际工作目录go env中的配置(看上去是如果配置全局 PATH=%GOPATH%\bin 就使用 GOPATH 中的go.exe和pkg)
    • 对于复杂的构建流程和依赖关系,有时还需要根据 Makefile 文件,执行 build来构建项目。
  • VSCode 连接 WSL的Linux环境 开发 Go 项目(先用ubuntu开发,后再centos验证)
    1
    2
    3
    4
    5
    6
    7
    D:\Users\caifeng7>wsl -l -v
    NAME STATE VERSION
    * Ubuntu Running 2
    CentOS7 Running 2

    D:\Users\caifeng7>wsl # 管理员cmd进入wsl的默认linux发行版
    root@caifeng7138:/mnt/d/Users/caifeng7#
    安装go到linux,配置ubuntu上的golang开发环境(centos使用yum管理包)
    1
    2
    sudo apt update
    sudo apt install golang-go
    将GOPATH/bin添加到的PATH环境变量中
    1
    2
    echo 'export PATH=$PATH:/root/go/bin' >> ~/.bashrc
    source ~/.bashrc
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    root@caifeng7138:/mnt/c/Windows/system32# go env
    GO111MODULE=''
    GOARCH='amd64'
    GOBIN='' # 编译后的二进制文件的存放位置
    GOCACHE='/root/.cache/go-build' # Go编译缓存的路径
    GOENV='/root/.config/go/env'
    GOEXE=''
    GOEXPERIMENT=''
    GOFLAGS=''
    GOHOSTARCH='amd64'
    GOHOSTOS='linux'
    GOINSECURE=''
    GOMODCACHE='/root/go/pkg/mod'
    GONOPROXY=''
    GONOSUMDB=''
    GOOS='linux'
    GOPATH='/root/go' # Go工作空间的根目录,用于存放你的Go项目和依赖。
    GOPRIVATE=''
    GOPROXY='https://proxy.golang.org,direct' # 修改代理 export GOPROXY=https://goproxy.cn,direct
    GOROOT='/usr/lib/go-1.22' # Go语言的安装目录,包含了Go的编译器、标准库和工具。
    GOSUMDB='sum.golang.org'
    GOTMPDIR=''
    GOTOOLCHAIN='auto'
    GOTOOLDIR='/usr/lib/go-1.22/pkg/tool/linux_amd64'
    GOVCS=''
    GOVERSION='go1.22.2'
    GCCGO='gccgo'
    GOAMD64='v1'
    AR='ar'
    CC='gcc'
    CXX='g++'
    CGO_ENABLED='1'
    GOMOD='/dev/null'
    GOWORK=''
    CGO_CFLAGS='-O2 -g'
    CGO_CPPFLAGS=''
    CGO_CXXFLAGS='-O2 -g'
    CGO_FFLAGS='-O2 -g'
    CGO_LDFLAGS='-O2 -g'
    PKG_CONFIG='pkg-config'
    GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffil...'
    VSCode使用WSL:Remote Explorer选择linux发行版,使用Ubuntu环境打开Go项目目录: /mnt/d/code/datamars-agent/
    此时自动下载了项目go.mod要求的go版本? 项目中的环境变量发生变化 ↓
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    root@caifeng7138:/mnt/d/code/datamars-agent# go env
    # 个人用户的Go工作空间。用于存放Go项目和依赖
    GOPATH='/root/go'
    # Go的安装目录,指向通过模块系统安装的一个特定版本(1.22.4),而不是 /usr/lib/go(全局路径)
    GOROOT='/root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.4.linux-amd64'
    # Go工具链的安装目录
    GOTOOLDIR='/root/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.22.4.linux-amd64/pkg/tool/linux_amd64'
    GOVERSION='go1.22.4'
    # Go模块缓存的路径
    GOMOD='/mnt/d/code/datamars-agent/go.mod'
    在WSL中,安装protoc,添加到PATH;
    执行make,通过makefile中的配置构建项目,编译proto文件,生成Go,grpc程序
    Protobuf 是一种由 Google 开发的用于序列化结构化数据的语言中立、平台中立的可扩展机制,Protoc 可以将 定义了数据结构和序列化规则的 .proto 文件编译生成包括 Go,Java的多种语言。用于grpc请求的数据同步。。