用现有的姿势去解锁新姿势的过程中会有写先入为主的错误,在解锁新姿势的过程中造成写麻烦。
最为一个自学go的c/c++码农,在简单扫过包这一概念时,直接把包理解成了.h文件。忽略了包的本质。由于go的数据定义方式,导致我花了两天时间也没有找到相当于“”命名空间“或者”static的全局变量“的功能,进而让我的程序不仅全局变量满天飞,而且功能模块的封装太差。直到需要单例的时候,差点放弃。最后发现这些是通过分包实现的。
.h文件曾经因为暴露私有成员而广受诟病。那么,包是如何做到的呢?通过结构体的初始化方式可以窥知一二
type Cat struct {
Arg int
}
cat := npk.Cat{Arg: 3}
c/c++是通过头文件信息,直接通过内存布局来初始化成员。但是go这里我们可以看出来,是使用名字初始化成员。据我所学,实现这种方法的最直接方式就是反射。想到这里也突然明白为什么go要通过首字母大小写来区分私有和公有。那么如何实现包内的全局数据保护问题的答案也浮出水面。
和c/c++是通过头文件信息,得到内存布局不同。go通过包内容的反射,对包外提供接口。这样,包一来实现了命名空间的功能(包内内容包外无法直接访问),二来实现了static全局变量的功能(首字母小写内容包外无法访问)。所以即使程序是个人完成,为了解耦,一个工程也要分割多个包。
这应该也是为什么go的初始化方式五花八门了。new方法 new关键字 make的疑惑也解决了。