Golang反射的使用的正确姿势

Golang反射的使用的正确姿势

Go本身不支持模板,因此在以往需要使用模板的场景下往往就需要使用反射(reflect). 反射使用多了以后会容易上瘾,有些人甚至会形成一种莫名其妙的鄙视链。文人相轻,看来在需要动手指的领域历来如此:) 。反射有两个问题,在使用前需要三思:

  1. 大量的使用反射会损失一定性能
  2. Clear is better than clever. Reflection is never clear.

Go的类型设计上有一些基本原则,理解这些基本原则会有助于你理解反射的本质:

  1. 变量包括 <type, value> 两部分。理解这一点你就知道为什么nil != nil了。
  2. type包括 static typeconcrete type. 简单来说 static type是你在编码是看见的类型,concrete type是runtime系统看见的类型。
  3. 类型断言能否成功,取决于变量的concrete type,而不是static type. 因此,一个 reader变量如果它的concrete type也实现了write方法的话,它也可以被类型断言为writer.
  4. Go中的反射依靠interface{}作为桥梁,因此遵循原则3. 例如,反射包.Kind方法返回的是concrete type, 而不是static type.

Talk is cheap, show some code:

Golang中使用gorm小结

Golang中使用gorm小结

项目中使用orm的好处很多:

  1. 防止直接拼接sql语句引入sql注入漏洞
  2. 方便对modle进行统一管理
  3. 专注业务,加速开发

坏处也是显而易见的:

  1. 开发者与最终的sql语句隔了一层orm,因此可能会不慎引入烂sql
  2. 依赖于orm的成熟度,无法进行一些「复杂」的查询。当然,复杂的查询一大半都是应该从设计上规避的

留意不合法的时间值

MySQL的DATE/DATATIME类型可以对应Golang的time.Time。但是,如果DATE/DATATIME不慎插入了一个无效值,例如2016-00-00 00:00:00, 那么这条记录是无法查询出来的。会返回gorm.RecordNotFound类型错误。零值0000-00-00 00:00:00是有效值,不影响正常查询。

留意tagsql:"default:null"

gorm对各种tag的支持非常完善。但是有些行为跟直觉不太一致,需要注意。当对某字段设置tagsql:"default:null"时,你想通过update设置该字段为null就不可能了,只能通过raw sql。这是gorm设计的取向问题。

如何通过gorm设置字段为null

字段允许为null值肯定是设计存在问题。但是,往往前人埋下的坑需要你去填。gorm作者给出了两种方法,以string为例:

  1. 在golang中,声明该字段为*string
  2. 使用sql.NullString类型

推荐使用后者。

留意连接串中的loc

例如通过如下连接串打开mysql连接:

parseTime=true&loc=Local说明会解析时间,时区是机器的local时区。机器之间的时区可能不一致会设置有问题,这导致从相同库的不同实例查询出来的结果可能解析以后就不一样。因此推荐将loc统一设置为一个时区,如parseTime=true&loc=America%2FChicago

GitLab搭建笔记

GitLab搭建笔记

GitLab使用Omnibus package搭建是分分钟就可以搞定的事情,但是我搭建的GitLab服务:

  1. 服务器在墙内;
  2. 服务器在一个路由器后面;

因此,浪费了一个晚上时间才把几分钟计划完成的事情搞定。这里给遇到类似情况的程序员做个简单的笔记,希望可以为他们节约一点时间吧。

服务器在墙内

Omnibus package(大小约340MB)通过AWS S3(AWS Region为美国新泽西)进行分发。墙内下载该package的速度极慢(电信百兆宽带下载速度约8KB/S),且部分时间段packages-gitlab-com.s3.amazonaws.com域名疑似被污染(四川成都地区)。因此,只好通过墙外的VPS中转下载。当前最新版(2015.08.30)为gitlab-ce_7.14.1-ce.0_amd64.deb. 上传了一份到百度网盘, 密码: qf38。阅兵在即,墙外要中转一个文件进来真是浪费生命,唉…

服务器在路由器后

这个比较好解决,需要映射两个端口。

  1. 映射Web端口: 映射路由器外部GitLab端口到GitLab配置端口(/etc/gitlab/gitlab.rb external_url ‘http://your-host:PORT’ );
  2. 映射SSH端口: 映射路由器外部GitLab SSH端口到22端口, 然后修改/etc/gitlab/gitlab.rb文件:
    • gitlab_rails[‘gitlab_shell_ssh_port’] = 路由器外部GitLab SSH端口
    • 注意:gitlab_rails[‘gitlab_shell_ssh_port’]只是配置代码库地址的端口,不会修改SSH真实使用的端口。
  3. sudo gitlab-ctl reconfigure