Go: 変数パラメータが展開されておらず、ピットを踏んでいないことを覚えておいてください

Go: 変数パラメータが展開されておらず、ピットを踏んでいないことを覚えておいてください


1.再発

私は当初、独自のエラー関数 test1280Error を実装し、固定プレフィックス識別子を持つエラー オブジェクトを生成したいと考えていました。

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[subscript] を通じて添字要素を指定できます。次に例を示します。

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