本文记录了作者在使用goland提供的提取方法(Extract Method)功能时,由于...interface{}的类型问题而遭遇到的bug和一点感悟,简单来说:
- 可变长的参数会被goland的Extract Method转化为切片(slice),比如
...interface{}会被转化为[]interface{} - 由于
interface{}的特殊性,需要额外注意
bug的产生
在代码中有如下片段
1 | func f(payload ...interface{}) { |
现在想要将循环提取出来,作为一个方法,在goland中可以直接选中文本然后Extract Method,但是结果是这样的
1 | func f(payload ...interface{}) { |
期望中的函数签名是ExtractedMethod(payload ...interface{}),不符合预期,所以要进行修改
1 | // WRONG!!!!!!!! |
上述的代码不会有编译错误,但是是完全不符合预期的,为什么呢?
bug的原因
1 | // WRONG!!!!!!!! |
如上述注释所说,我们需要对f中传递给ExtractedMethod的参数payload做一个解包工作,因为
- 我们
f函数的本意是要用ExtractedMehtod对payload中的每一个元素做处理 - 现在不解包,
payload原本一个[]interface{}又被额外自动包装了一层,成为了interface{}传递给了ExtractedMethod,只会对整个payload做一次处理
bug的解决与思考
将代码修改为如下后正确
1 | func f(payload ...interface{}) { |
以后可以采取的方法是,先将传参的地方payload改为payload...,这样的话如果忘记修改参数[]interface{}为...interface{},是会有编译器报错的
这个修改顺序可以让编译器为我们保驾