今天在看一个 golang 项目的源码时,有几个地方没明白,然后顺手谷歌了一会,初步知道了原因。
1、验证结构体是否实现了某个接口
假设接口如下:
type IModule interface {
Name() string
Version() string
}
某个需要实现该接口的结构体如下:
type StatModule struct {
}
现在的问题是,如何确保 StatModule 实现了 IModule,当然可以人工核对,但未免太费精力,而且人工也容易出错,那当然要去寻找自动核对的方法了,目前有两种:
其中一种基本上会用到,即在参数传递的时候,当把该结构体的对象传到以该接口为形参的方法中时,编译器会报错,提示结构体未实现接口。
另外一种保险的做法是,在结构体定义处定义一个匿名结构体对象,类型为接口:
var _ IModule = &StatModule{}
type StatModule struct {
}
2、通过编译选项给 golang 包中的变量赋值
发现文件有几个全局变量并未在源码中有对应的赋值语句,但是有代码使用了它们,那 c/c++ 开发经验的朋友肯定会想,这不就是使用了未初始化的变量,但在 golang 中,这些变量的赋值还可以通过编译选项 -ldflags 来指定,比如 main 包有 build、commit、host、version 几个全局变量,那么在编译的时候可以通过下面的命令来指定它们的值:
go build -o main -ldflags "-X main.build="`date '+%Y-%m-%dT%H:%M:%S%z'`" -X main.commit="123456" -X main.host="`hostname`" -X main.version="" "
3、viper 监听配置文件更改
服务端经常需要配置各种各样的参数,viper 包对于参数解析来说功能非常丰富,简单易用,
如果需要修改配置文件,而不重启服务怎么办呢,可以在初始化函数里面调用 viper.OnConfigChage() 和 viper.WatchConfig() 来实现这一目的,这两个函数的先后顺序没有要求, 但是需要在调用 viper.WatchConfig() 之前完成配置文件的读取,否则 WatchConfig 无法知道监听哪个配置文件的更改。
当你使用编辑器或者 echo 命令修改完配置文件后,viper 会立马感知到这次修改。但如果使用 truncate 命令对配置文件的大小进行修改了,比如清空配置文件了(truncate -s 0 cfgfile), viper 无法感知到。
但 viper 仅仅是监听配置文件修改而已,至于修改后要做什么事情,就需要开发人员控制了,当然在程序中稍后会用到的配置项内容也会更新,如果配置项只在程序启动时用了一次,那么即使修改了也不会生效,比如监听的端口。
因此如果要不重新启动服务来修改服务经常会用到的配置项,那么 viper WatchConfig 是一个不错的选择,但如上所述,它有自己的局限性,不如 nginx 的 reload 那么强大