go语言测试

  • 使用_test做为包名做黑盒测试, 使用import . xxx导入要测试的包, 有时为了打破循环引用也需要用这种方式
  • t.Skip(), 当检测到有些测试条件不满足时(比如外部依赖,环境变量没设等情况)可以跳过这个case
  • go test -short, TestCase里用testing.Short判断用户使用了-short参数时,可以做判断跳过耗时的case
  • go test -timeout 1s, 指定耗时, 超时就失败
  • go test -run TestNameRegexp 只执行指定的测试用例
  • t.Parallel() 标记为可以并行测试, 在Test case函数体一开始就调用

参考链接

https://splice.com/blog/lesser-known-features-go-test/

go语言槽点

想起一条写一条,
之后尽量补上例子和理想的做法

定义类型的地方允许x, y, z int这种写法表示x, y, z均为int型

可读性不好

没有重载

许多package里看到大片的XXXInt, XXXInt64, XXXUint64, ...
视觉污染, 写代码麻烦, 改代码也麻烦

defer

  • 可读性不好, 本身就已经颠覆了一般性的顺序执行思维, 写在前面, 执行却在后面,
    而且多条defer在一起还是LIFO顺序, 真是counter-intuitive,
    还是像其他语言那样try finally比较好, 或者像python, C#那样有with语句更好,
  • 容易引发bug, 因为defer可以修改return语句的值, 使得return语句处具有不确定性,
    使得程序员容易搞错

var, :=, =

太容易出错了, 何必整这么多种, 而且a, b := xxx时, a, b中有一个未定义也合法, 简直dirty
编译后经常报:=前面没有新变量,然后去改成=号,许多时间就浪费在这种事情上
像python或erlang那样都是=对大家都好
平白增加程序员需要处理的细节, 与go宣传的简单化背道而驰

没有implement这样的关键字

无意中就实现了某interface{},
违背了程序员的意志,
带来意想不到的问题

closure做得不对

直接定义一个匿名函数,函数用到的外部变量并不是当时的变量快照,而是一个引用,
想要真正的closure需要用传参来做.
https://www.goinggo.net/2014/06/pitfalls-with-closures-in-go.html

一个package可以对应多个文件

函数定义还需要到别的文件里去找. import语句也重复了

没有泛型

返回error

每一层函数调用都要check一遍,到处都充斥着if err != nil
中间层函数只是因为调到了返回error的函数,自己的返回值也被迫加上error

没有条件表达式

当然这个不是什么致命伤,
但是需要的时候发现go代码写起来巨麻烦,
其实希望最好像函数式编程那样一切都是表达式,if或case等都能有一个返回值

优点

gofmt

虽然别的语言也可以一个插件搞定, 不过go这方面做得不错
由于是官方提供的, 大家就统一了

python

virtualenv

沙箱机制
ubuntu 14.04用的是python 2.7.6, 有些旧了
自己上python官网下载了2.7.12的源码并编译安装,
创建virtualenv使用如下命令, 在新环境里使用2.7.12

1
virtualenv --python=/usr/local/bin/python venv

解决问题: 自己编译的python,方向键不能用

原来是编译时缺一些dev, 没有编译readline

1
2
3
4
sudo apt-get install libreadline6 libreadline6-dev
sudo apt-get install libgdbm-dev
sudo apt-get install libsqlite3-dev
sudo apt-get install libbz2-dev

有第一个就可以解决方向键的问题,剩下的是其他依赖,
不需要的话就可以不管
做完这些之后再重新编译一遍python就好

1
2
sudo apt-get install python-dev
sudo easy_install gnureadline