Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Go 基础知识 #50

Open
zhongdeming428 opened this issue Jun 19, 2022 · 0 comments
Open

Go 基础知识 #50

zhongdeming428 opened this issue Jun 19, 2022 · 0 comments
Assignees

Comments

@zhongdeming428
Copy link
Owner

zhongdeming428 commented Jun 19, 2022

该文档只记录了我认为需要记录的部分,太过于基础或者细节的内容会被忽略。

1 常用环境变量

Go 语言通过环境变量来指导一系列的活动,比如编译、运行、代码组织、依赖下载等等。

下面是 Go 语言中我们常用的一些环境变量及其含义:

GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOENV="/Users/demingzhong/Library/Application Support/go/env"
GOEXE=""
GOOS="darwin"
GOPATH="/Users/demingzhong/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/usr/local/go"
GOVERSION="go1.17.3"
GOMOD="/Users/demingzhong/Documents/Work/entry-task/go.mod"
  • GO111MODULE: 是否启用 Go 1.11 引入的 Go Modules 功能组织代码,Go 1.11 之前我们的项目需要放置于 GOPATH 环境变量指定的路径中。Go 1.11 开启这个功能之后,我们的项目可以放置在任意路径。
    更加详细的说明:https://learnku.com/go/t/39086。
  • GOARCH & GOOS:指定编译的目标架构和目标操作系统,比如 GOARCH="amd64" GOOS="darwin"。
  • GOBIN:使用 go install 命令编译打包安装应用程序之后,可执行文件放置的位置,默认路径是 GOPATH/bin。
  • GOENV: 指定环境变量配置文件的位置。
  • GOEXE:指定生成的可执行文件的扩展名,(".exe" on Windows, "" on other systems)。
  • GOPATH:GOPATH 用于指定我们的开发工作区(workspace),是存放源代码、测试文件、库静态文件、可执行文件的工作。默认为 home 目录下的 go 目录。
    其内部存放着 bin、src、pkg 三个目录,其中 bin 目录主要存放 go install 打包安装的二进制文件,src 存放我们的项目源代码,pkg 存放下载的其他项目的库,即使开启了 Go Modules 功能,安装的第三方包也会放置在这个位置。
  • GOPRIVATE:指定私有仓库的地址,比如 git.garena.com,配置之后可以跳过 proxy 的检查。
  • GOPROXY:指定下载的代理,公司的网络没有被墙,不需要设置这个参数。
  • GOROOT:go 的安装目录。
  • GOVERSION:go 版本。

参考:https://juejin.cn/post/6844903817071296525#heading-3

2 常用命令

  • build:将项目编译成二进制可执行文件,基本使用形式:go build -o [output] xxx.go。
    -o 参数指定输出路径。
    -race 输出竞态分析结果。
    -ldflags:传递一些影响编译过程的参数,比如去掉符号表,去掉调试信息,比较实用。
  • env:列出/设置第一节中指定的各种环境变量。
  • fmt:对代码进行格式化,IDE 可以自动帮我们做这件事。
  • generate:命令是在Go语言 1.4 版本里面新添加的一个命令,当运行该命令时,它将扫描与当前包相关的源代码文件,找出所有包含 //go:generate 的特殊注释,提取并执行该特殊注释后面的命令。
    像 Gomock 这种包就可以通过 generate 命令直接生成很多个 mock 文件。
  • get:借助代码管理工具通过远程拉取或更新代码包及其依赖包,并自动完成编译和安装。
    -d 只下载不安装。
    -insecure 通过 http 下载安装(不安全)。
    -u 强制使用网络去更新包和它的依赖包。
  • install:编译并安装可执行文件到 GOPATH/bin 目录下。
  • mod:针对 modules 进行管理。
  • download:下载三方模块到本地缓存。
  • init:初始化模块,新建项目的时候使用。
  • tidy:整理 go.mod 文件,移除不再使用的模块,添加新安装的模块。
  • run:运行 go 程序。
  • test:测试 go 包。
    -cover 参数可以输出覆盖率。

参考:https://blog.51cto.com/u_13107138/2767314

3 Array & Slice

3.1 Array

  • 数组长度是类型的一部分,所以长度不同的数组属于不同类型。
  • 数组在 Go 中是值类型,数组变量的地址等于数组中第一个元素的地址。
  • 因为数组是值类型,所以在赋值时会发生值拷贝,修改拷贝后的数组不会影响拷贝之前的数组(对比之下 slice 的结果会不一样)。
  • 数组之间可以通过 == 和 != 进行比较。

3.2 Slice

  • 复杂(引用)类型,底层通过数组存储数据,作为变长数组的替代方案。
  • 因为切片是引用类型,所以修改拷贝之后的切片会影响拷贝之前的切片,除非拷贝之后的切片因为 append 操作导致扩容而重新开辟了一块内存空间。
  • len() 获取元素个数,cap() 获取容量大小。
  • 多个 slice 引用同一个底层数组时要注意修改操作会导致互相之间的影响。
  • 通过 make([]T, len) 进行初始化赋值时,忽略了 cap 参数,此时创建出来的切片的 cap 等于 len。
  • 切片在 append 操作导致容量不足时会导致扩容,这一过程中会发生数组元素的 copy,开销比较大。
  • 扩容操作默认每次扩充现有容量的 100%(比如现在 cap 为 10,扩容之后变成 20),当切片容量超过 1024 时,下次扩容 125%。

4 Map

  • map 类型的变量只能跟 nil 进行 ==/!= 比较,否则会报错。
  • map 的 key 必须是支持 ==/!= 比较的数据类型,所以 map 的 key 不能为 slice/map...。
  • 通过 make(map[k]v, cap) 创建 map,cap 代表容量,支持通过 len() 获取元素个数。
  • 通过 delete 删除 map 元素。

5 defer

  • 在函数体执行完毕之后执行,执行时机在 return 之后,函数移出调用栈之前。
  • 执行的顺序和代码中的调用顺序相反,从下往上执行。
  • 即使函数发生了严重错误也会执行。
  • 一般用于资源释放(锁、文件句柄、网络连接等)、panic 处理等操作。
  • 由于执行时机在 return 之后,所以 return 返回值可能会被 defer 操作修改,需要注意。

6 结构体

  • 一般情况下结构体支持 ==/!= 比较操作,但是当结构体中具有不能通过 ==/!= 进行比较的成员时会报错
  • 支持匿名字段,本质上还是定义了以类型名称为名字的字段。
  • 嵌入结构匿名字段看起来像是继承,但是不是继承。
  • 如果外部结构和内部嵌入结构具有相同的方法名称,则优先调用外部结构的方法。
  • 类型别名不会拥有底层类型上的方法。

7 接口

8 Channel

  • Channel 是引用类型,可以通过 close 关闭 channel,一般在写侧关闭 channel,在读侧检测 channel 是否已关闭(ok pattern)。
  • Channel 默认是阻塞的,需要创建带 buffer 的 channel 以避免阻塞。
  • 带 buffer 的 channel(比如 make(chan uint, 10)),在写数据时只有在 buffer 满了的时候才会阻塞,读数据时只有在 buffer 空了的时候才会阻塞。

9 Select

  • 处理一个或多个 channel 的读写操作。
  • 当多个操作同时可以触发时,使用伪随机算法选一个操作继续进行。
  • 可使用空的 select 阻塞协程。
  • 可以通过带有定时功能的 channel 实现超时功能。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant