goland提取方法与...interface{}类型的注意点

本文讲述了作者在Goland中使用Extract Method功能时遇到的问题,由于interface{}类型导致的bug及其解决思路。当可变长参数被转换为slice,可能会引发预期不符。解决方案是确保对interface{}参数进行解包,以避免只处理整个slice而非单个元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文首发于我的Github博客
本文记录了作者在使用goland提供的提取方法(Extract Method)功能时,由于...interface{}的类型问题而遭遇到的bug和一点感悟,简单来说:

  • 可变长的参数会被goland的Extract Method转化为切片(slice),比如...interface{}会被转化为[]interface{}
  • 由于interface{}的特殊性,需要额外注意

bug的产生

在代码中有如下片段

func f(payload ...interface{}) {
    for _, p := range payload {
        // do something
    }
}

现在想要将循环提取出来,作为一个方法,在goland中可以直接选中文本然后Extract Method,但是结果是这样的

func f(payload ...interface{}) {
    ExtractedMethod(payload)
}

func ExtractedMethod(payload []interface{}) {
    for _, p := range payload {
        // do something
    }
}

期望中的函数签名是ExtractedMethod(payload ...interface{}),不符合预期,所以要进行修改

// WRONG!!!!!!!!

func f(payload ...interface{}) {
    ExtractedMethod(payload)
}

func ExtractedMethod(payload ...interface{}) {
    for _, p := range payload {
        // do something
    }
}

上述的代码不会有编译错误,但是是完全不符合预期的,为什么呢?

bug的原因

// WRONG!!!!!!!!

func f(payload ...interface{}) {
    // we need to unpack payload
    ExtractedMethod(payload)
}

func ExtractedMethod(payload ...interface{}) {
    for _, p := range payload {
        // do something
    }
}

如上述注释所说,我们需要对f中传递给ExtractedMethod的参数payload做一个解包工作,因为

  • 我们f函数的本意是要用ExtractedMehtodpayload中的每一个元素做处理
  • 现在不解包,payload原本一个[]interface{}又被额外自动包装了一层,成为了interface{}传递给了ExtractedMethod,只会对整个payload做一次处理

bug的解决与思考

将代码修改为如下后正确

func f(payload ...interface{}) {
    ExtractedMethod(payload...)
}

func ExtractedMethod(payload ...interface{}) {
    for _, p := range payload {
        // do something
    }
}

以后可以采取的方法是,先将传参的地方payload改为payload...,这样的话如果忘记修改参数[]interface{}...interface{},是会有编译器报错的

这个修改顺序可以让编译器为我们保驾

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值