これは Go 4 Advent Calendar 2020 の19日目の記事です。
0. まえがき
数値から文字列に変換する関数として、strconv.Itoaがありますが、ソースコードの中身が気になったので、見てみます
1. 実行環境
- Windows10 Home
- go version go1.14.4 windows/amd64
2. 数値を文字列に変換する関数 strconv.Itoa
int型の任意の数値を、string型に変換する関数
https://golang.org/pkg/strconv/#Itoa
2-1. 0を"0"に変換して表示する
package main
import (
"fmt"
"strconv"
)
func main() {
var n int = 0
nString := strconv.Itoa(n)
// nString: 0 と表示される
fmt.Printf("nString: %s\n", nString)
}
3. 実際何やっているの?
strconv.Itoaの動作が分かったところで、実際の処理を見ていきます
strconv.Itoaのソースコード:https://golang.org/src/strconv/itoa.go
3.1 func Itoa(i int) string
まずは、関数の本体(?)を見ます
func Itoa(i int) string {
return FormatInt(int64(i), 10)
}
なるほど、関数FormatIntに「int64型にキャストしたi」と「10」を渡していますね。今回は、iは0になります。
3.2 func FormatInt(i int64, base int) string
次に、FormatIntを見ます
func FormatInt(i int64, base int) string {
if fastSmalls && 0 <= i && i <= nSmalls && base == 10 {
return small(int(i))
}
_, s := formatBits(nil, uint64(i), base, i < 0, false)
return s
}
まずは、以下のif文についてですが、
if fastSmalls && 0 <= i && i <= nSmalls && base == 10 {
return small(int(i))
}
fastSmalls は、ソースコード中で定義されており、「true」となります。
const fastSmalls = true
また、nSmallsは、ソースコード中で定義されており、「100」となります。
const nSmalls = 100
今回、iは0, baseは10となっているので、それぞれの変数に値を当てはめると、if文は以下のようになります。
if (true && 0 <= 0 && 0 <= 100 && 10 == 10) {
return small(int(i))
}
よって、if文がtrueになるため、次の関数のsmall(int(i))に行きます。
3.3 func small(i int) string
smallは以下のようになります。
func small(i int) string {
if i < 10 {
return digits[i : i+1]
}
return smallsString[i*2 : i*2+2]
}
iは0なので、if文に入ってdigits[0 : 0+1]を返します。digitsはソースコード中で以下のように定義されています。
const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
digits[0 : 0+1]より、"0"が返ってきます。
4. 結論
0をstrconv.Itoaに渡すと、digits[0 : 0+1]より、"0"が返ってくる
5. まとめ
今回は0を"0"に変換するということでソースコードの一部しか見ていませんが、もっと大きな数値になると変換の処理が変わってきます。そちらの処理の中身の確認は皆さんにおまかせします。普段何気なく使っている関数でもそのソースコードを見ることは少ないと思います。とても勉強になるので皆さんも、普段使う関数のソースコードを読んでみてはいかがでしょうか。