go中关于[]interface的小错误

最近工作中在做一些功能测试和代码重构,出现了一个挺有意思的小问题,最开始排查的时候竟然还花了一小会才定位到问题,结果也让我多少有点哭笑不得,也算是一个小知识点吧。

问题描述:

需求是将个数据来源中,一个相同的属性进行合并去除重复,而结果中显示的内容是比预期要少,也就是出现了漏掉一部分熟悉的情况,而我看了一圈代码没有发现问题,这里简单贴一下代码:

func TestInterfaceSplit(t *testing.T) {
	strA := []interface{}{"a", "b"}
	strB := []interface{}{"b", "c"}

	strA = append(strA, strB)

	t.Log(removeDuplicates(strA))
/*
输出结果:
[a b]
预期结果:
[a b c]
*/
}

func removeDuplicates(interfaceSplit []interface{}) (strSplit []string) {
	strMap := make(map[string]uint)
	for _, value := range interfaceSplit {
		str, ok := value.(string)
		if !ok {
			continue
		}
		strMap[str] = 0
	}

	for key := range strMap {
		strSplit = append(strSplit, key)
	}

	return
}

排查过程:

因为原本业务中稍微有一些复杂,所以首先排查了一下功能逻辑,一个拼接,一个利用map的hash特性进行去重也很简单,所以检查了一下数据输入,结果发现数据来源没有问题,于是为又回头看了一下代码,突然一拍脑袋,原来问题在这里,[]interface这个切片的问题!

原因:

在go语言中,interface可以理解为是所有类型的父接口,而在这里,因为来源的问题,所以使用了[]interface作为一个统一处理的位置,问题就出现了append这里,因为[]interface也被认为是一个interface本身了,所以实际上过程中出现了一个小错误,代码解释一下:

strA := []interface{}{"a", "b"}
strB := []interface{}{"a", "b", "c"}

strA = append(strA, strB)
// str--> [a b [a b c]],问题就出在了这个里,结果不是预期的[a b a b c],第三个元素是strB本身,所以在去重时,因为类型的边界检查给跳过,而有没有一个好的log来记录过程,所以没有第一时间定位到问题。

解决方法也比较简单,就是在append给一个[]interface时,如果是想append内容,而不是一个切片本身的话,可以使用语法糖进行打散操作:

strA = append(strA, strB...) // ...在go中可以起到一个打散的作用
t.Log(strA) // [a b a b c]

一个很简单的小问题,但是也是很基础的问题,简单记录一下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值