Go Modules 历史变迁

Go 分类文章,学习笔记,会不定时修改,补充,纠错,增加内容,路漫漫。

两种包管理运行模式

  • GOPATH mode,从 vendorGOPATH 下寻找依赖,依赖会被下载至 GOPATH/src 目录下
  • module-aware mode

Go 1.11 – 2018.8

正式推出 go modules ,可以查看 go help modules 获取相关信息

GO111MODULE

新增的环境变量,用于控制 Go 代码包管理运行模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
For more fine-grained control, the module support in Go 1.11 respects
a temporary environment variable, GO111MODULE, which can be set to one
of three string values: off, on, or auto (the default).
If GO111MODULE=off, then the go command never uses the
new module support. Instead it looks in vendor directories and GOPATH
to find dependencies; we now refer to this as "GOPATH mode."
If GO111MODULE=on, then the go command requires the use of modules,
never consulting GOPATH. We refer to this as the command being
module-aware or running in "module-aware mode".
If GO111MODULE=auto or is unset, then the go command enables or
disables module support based on the current directory.
Module support is enabled only when the current directory is outside
GOPATH/src and itself contains a go.mod file or is below a directory
containing a go.mod file.

In module-aware mode, GOPATH no longer defines the meaning of imports
during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod)
and installed commands (in GOPATH/bin, unless GOBIN is set).
  • GO111MODULE = auto,默认值(设置为 auto 或者不设置)
    • 在 GOPATH/src 目录外,且文件夹包含 go.mod 文件,就运行 module-aware mode,其余情况都是 GOPATH mode
  • GO111MODULE = on,开启
    • 不管目录所在路径,都是 module-aware mode
    • 运行 go build 等命令,会优先判断 go.mod 是否存在,不存在的话,先创建 go.mod 文件
  • GO111MODULE = off,关闭
    • 任何情况下,都关闭

包下载路径

  • module-aware mode 在 GOPATH/pkg/mod 目录下
  • GOPATH mode 在 GOPATH/src 目录下

Go Get

运行在不同 mode 下,行为不同

  • module-aware mode 会修改 go.mod 文件
  • GOPATH mode ,按照之前的行为运行

Go Get 存在的问题

如果 GO111MODULE = on ,且当前目录没有 go.mod 文件,会报错 go: cannot find main module; see 'go help modules'

vendor 目录支持

运行 go mod vendor ,会在当前目录生成 vendor 目录,从 GOPATH/pkg/mod 复制 packge 过来

运行命令类似,go build -mod=vendor 加上 -mod=vendor,会使用 vendor 目录下依赖,否则还是使用 GOPATH/pkg/mod 下依赖

GOPROXY

新增 GOPROXY 环境变量,用于设置 go module 下载代理地址

My New Article In 2020

许久未更新了。
生疏到 markdown 语法都已经忘记了。
眼看 2020 就要过去了。
还是需要练练手。
就当是为了 2021 可以相对持续的更新吧。
生活还在继续。
只是中年,庸人自扰。
望一切都好。

Go 阅读 negroni 源码

Go 分类文章,学习笔记,会不定时修改,补充,纠错,增加内容,路漫漫。

negroni 提供 golang 常用的中间件使用方式,项目地址 https://github.com/urfave/negroni/

阅读版本是 2019.6.2 的 7d1c5e commit

GoDoc - https://godoc.org/github.com/urfave/negroni

前提知识

了解 net/http server 的相关知识,也可以读我写的上一篇 【http-server】

基本使用

1
2
3
4
5
6
7
8
9
10
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page! "+req.URL.Path)
})

n := negroni.New()
n.Use(negroni.NewLogger())

n.UseHandler(mux)
n.Run(":3000")

其中关于 mux 变量的部分,可以参考上一遍 http-server,这里就不说明了,主要关注 n := negroni.New()

Go HTTP Server 使用分析

Go 分类文章,学习笔记,会不定时修改,补充,纠错,增加内容,路漫漫。

使用 net/http 包处理 http request

GoDoc - https://godoc.org/net/http

net/http 主要包括两部分

  • client
  • server

这里就是关于 server 部分

Tip: go version go1.12.4 darwin/amd64

Handler interface

查看 http.ListenAndServe 定义

1
2
3
4
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}

会发现第二个参数是 Handler 类型

1
2
3
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}

Handler 是一个接口定义,只要实现了 ServeHTTP(ResponseWriter, *Request) 方法的类型,都可以

Go - var & make & new 在复杂类型上的使用区别

Go 分类文章,学习笔记,会不定时修改,补充,纠错,增加内容,路漫漫。

这里主要讲解 var & make & new 在声明变量关于 array、slice、map、struct 这些类型上的区别。

预备知识

var 声明变量

var 变量名字 类型 = 表达式 ,如果省略了表达式,就使用类型的零值初始化变量

make 和 new 的知识

可以查看 GoDoc - builtin 的相关内容

  • new
    • func new(Type) *Type
    • 创建一个 Type 类型的匿名变量,初始为 Type 类型的零值,返回变量地址,返回的指针类型为*Type
  • make
    • func make(t Type, size ...IntegerType) Type
    • 分配并初始化一个类型为 slice 、map 、或 channel 的对象,返回类型与 Type 相同,而非指向它的指针

零值

  • array、struct,每个元素或字段都是对应该类型的零值
  • slice、map,对于零值 nil

排序算法

Algorithms 分类文章,为了在下次又忘记又想想起来的时候,稍微快速的回想一下。

排序方法很多,仔细想想还是快排最实用
冒泡排序、选择排序、桶排序、快速排序、归并排序、堆排序

群晖 Nas 使用 SSH Key 实现免密登录

最近直观的加上了文章访问统计和整站访问统计,虽然知道肯定没人访问,也就是纯粹加点新功能,但是没想到,关于 Nas 的文章访问量遥遥领先。

承接之前关于 Nas 的文章

开启了 VPN 可以更安全的访问 Nas ,同时我也需要使用 SSH 功能,但是每次使用的时候,都要输入密码,很是麻烦,如果能改成 ssh 免密登录就好了。
本质上跟其他的 linux 服务器设置免密登录原理差不多,稍微有点差别吧。

Go Method Receiver 方法接收器介绍

Go 分类文章,学习笔记,会不定时修改,补充,纠错,增加内容,路漫漫。

Receiver 基本介绍

就是类似于 Class 的 Method,使用 this 或者 self 调用 ?可以这么类比吧,但是并不等同。

看具体的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type IntReceiver struct {
X int
}

// 方法接收器声明
func (i IntReceiver) Double() int {
return i.X * 2
}

// 普通函数声明
func IRDouble(i IntReceiver) int {
return i.X * 2
}

func main() {
i := IntReceiver{3}
d1 := i.Double() // 在 i 上调用了 IntReceiver 类型带的 Method // func (i IntReceiver) Double() int
fmt.Printf("type = %T,value = %v\n", d1, d1)

d2 := IRDouble(i) // 调用了普通函数 // func IRDouble(i IntReceiver) int
fmt.Printf("type = %T,value = %v\n", d2, d2)
}

定义 method 并不局限于结构体 struct,可以任何 type 声明的类型定义 Method,最简单如 type DInt int ,就能为 DInt 类型定义 method

Go 运行的初始化

Go 分类文章,学习笔记,会不定时修改,补充,纠错,增加内容,路漫漫。

结论

先上简单结论

  • 初始化依赖包,也就是 import 的包
  • 在同一个包内,在解决依赖顺序的情况下,按照变量、常量出现的顺序依次初始化
  • 按照 init 函数出现的顺序运行
  • 运行 main 函数