覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Go言語 - 置換文字列を一部置換しなかったらどうなるの?

fmt.Sprintf などでフォーマット文字列を置換する場合に、置換対象のパラメータが複数あることもあります。
その際に、置換すべき値の数が合わないとどうなってしまうのかな?と思って一応試してみました。

http://127.0.0.1:%d/%s というフォーマット用の文字列があって、ポート番号とコンテキストパスにあたる部分の値を与えて、URLを完成させたい
という例で試してみます


正しく置換する

フォーマット上の変数の数と置換する値を合わせます


■サンプルコード

import "fmt"

func main() {
    fmtString := "http://127.0.0.1:%d/%s"
    result0 := fmt.Sprintf(fmtString, 8080, "app")
    fmt.Printf("0-A >> Format replace value. [%s] -> [%s]\n", fmtString, result0)
}


■実行結果

0-A >> Format replace value. [http://127.0.0.1:%d/%s] -> [http://127.0.0.1:8080/app]

ほしかった文字列が得られています。


パラメータに対して値が不足している

フォーマット上の変数の数に対して置換する値の数が少なかった場合にどうなるか試してみます。


■サンプルコード

import "fmt"

func main() {
    fmtString := "http://127.0.0.1:%d/%s"
    result1 := fmt.Sprintf(fmtString, 8080)
    fmt.Printf("1-A >> Format replace value. [%s] -> [%s]\n", fmtString, result1)
}


■実行結果

1-A >> Format replace value. [http://127.0.0.1:%d/%s] -> [http://127.0.0.1:8080/%!s(MISSING)]

置換すべき値が無かった場合、置換用の記述(今回の場合 %s)のまま残ったりしないかななんて期待しましたが、そんなアホなことはありませんでした。
不足してた部分が、 %!s(MISSING) という文字列になってしまっています。


パラメータに対して値が多い

フォーマット上の変数の数に対して置換する値の数が多かった場合にどうなるか試してみます。


■サンプルコード

import "fmt"

func main() {
    fmtString := "http://127.0.0.1:%d/%s"
    result2 := fmt.Sprintf(fmtString, 8080, "app", "/dummy")
    fmt.Printf("2-A >> Format replace value. [%s] -> [%s]\n", fmtString, result2)
}


■実行結果

2-A >> Format replace value. [http://127.0.0.1:%d/%s] -> [http://127.0.0.1:8080/app%!(EXTRA string=/dummy)]

多くて余ってしまう値(置換部分に当てはまらない値)のことは無視してくれるかなとか期待しましたが、そんなアホなことはありませんでした。
余計な値の分、 %!(EXTRA string=/dummy) という文字列が付与された結果になってしまっています。


まとめ

置換パラメータの数と置換する値の数が合わなかったりすると結果がおかしなことになるので、ちゃんと数を合わせましょう。

実際のところ、公式のドキュメントにもっと色々詳しく書いてあります。