Go:记一次可变参数未展开踩坑

Go:记一次可变参数未展开踩坑


1.复现

原想要实现自己的错误函数test1280Error,生成带有固定前缀标识的error对象。

import "fmt"

func main() {
    
    
	fmt.Println(test1280Error("msg: %s %s", "connection refused", "127.0.0.1:80"))
}

func test1280Error(format string, args ...interface{
    
    }) error {
    
    
	return fmt.Errorf("test1280 error: "+format, args)
}

测试发现,在处理错误函数test1280Error可变参数时,输出和预期不一致:

实际输出:

$ go run main.go
test1280 error: msg: [connection refused 127.0.0.1:80] %!s(MISSING)

期望输出:

$ go run main.go
test1280 error: msg: connection refused 127.0.0.1:80

2.解决

修改test1280Error错误函数中args调用:

修改前:

func test1280Error(format string, args ...interface{
    
    }) error {
    
    
	return fmt.Errorf("test1280 error: "+format, args)
}

修改后:

func test1280Error(format string, args ...interface{
    
    }) error {
    
    
	return fmt.Errorf("test1280 error: "+format, args...)
}

3.原因

一时疏忽,在test1280Error错误函数中,没有正确展开可变参数args导致。

a.可以通过args[下标]来访问可变参数args指定下标元素,例如:

import "fmt"

func main() {
    
    
	fmt.Println(test1280Error("msg: %s %s", "connection refused", "127.0.0.1:80"))
}

func test1280Error(format string, args ...interface{
    
    }) error {
    
    
	return fmt.Errorf("test1280 error: "+format, args[0], args[1])
}

执行结果:

$ go run main.go
test1280 error: msg: connection refused 127.0.0.1:80

b.可以通过args…展开可变参数

上述方法行不通,因为args中参数数量在变化,因此不能显示指定args[0], args[1]…访问。

假设可变参数args分别是1,2,3,则:args[0]=1, args[1]=2, args[2]=3。

return fmt.Errorf("test1280 error: "+format, args[0], args[1], args[2])

可以使用如下代码替代:

return fmt.Errorf("test1280 error: "+format, args...)

args…将展开成为args[0], args[1], args[2],如同字符串替换一样。

猜你喜欢

转载自blog.csdn.net/test1280/article/details/119829655
今日推荐