こんばんは、しーまんです。
今回は完全に個人的な備忘録です!
最近Go言語で開発する場面が増えているのですが、いつも型変換(キャスト)に悩まされます。
なるべくキャストはせずに開発するのがよいということは分かっているのですが、使用するモジュールに合わせて型変換をする場面がどうしても出てきてしまします。
全てのモジュールがインターフェースでどの型にも対応なんて都合の良い感じにはできていませんからね。
自身が開発しているシステムとモジュール間で微妙に型が違うなんて場合はないでしょうか。例えば同じ整数でもintとint64とか。
そういった場合の型変換の方法を毎回検索していて、流石に疲れたので一通りまとめようと思いました。
同じように型変換について悩んでいた人にとっては参考になるかもしれません。
数値型から数値型
まずは数値型から数値型の型変換についてまとめていきます。
大体の言語では数値型に関しては自動で大きい方というか、32ビットと64ビットだったら64ビットに置き換えてくれたり、intやdoubleなど整数と小数だったら小数に合わせてくれたりを自動で判断して行ってくれる言語が多いですが、Golangではそのあたりの融通は利きません。
しっかりと対応した型を指定しないとコンパイルエラーとなります。
これは型を意識しないで予期せぬ処理が走ることを防ぐ狙いがあるということは分かりますが、少し窮屈に感じる部分でもあります。
普通の言語では文字列型から数値型とその逆を考えるのがほとんどですが、Golangでは数値型同士の型変換も意識しなくてはいけません。ですのでまずはここからまとめていきましょう。
intからint64
var i int = 123
i64 := int64(i)
intからint32
var i int = 123
i32 := int32(i)
int64からint
var i64 int64 = 123
i := int(i64)
※ 桁あふれに注意しましょう。
int32からint
var i32 int32 = 123
i := int(i32)
intからuint
var i int = 123
ui := uint(i)
※ 負の値のキャストに注意しましょう。
uintからint
var ui int = 123
i := int(ui)
intからfloat64
var i int = 123
f64 := float64(i)
intからfloat32
var i int = 123
f32 := float32(i)
float64からint
var f64 float = 123.456
i := int(f64) // 123
※ 小数点以下の切り捨てに注意
float32からint
var f32 float = 123.456
i := int(f32) // 123
※ 小数点以下の切り捨てに注意
数値型から文字列型
数値型の型変換ができれば後は他言語と同じです。
数値型と文字列型の型変換をまとめていきましょう。
intからstring
import "strconv"
var i int = 123
s := strconv.Itoa(i)
int64からstring
import "strconv"
var i64 int64 = 123
s := strconv.FormatInt(i64, 10)
※ 64ビットより小さいものをまずは64ビットの数値型に変換する必要があります。
uint64からstring
import "strconv"
var ui64 uint64 = 123
s := strconv.FormatUint(ui64, 10)
※ 64ビットより小さいものをまずは64ビットの数値型に変換する必要があります。
float64からstring
import "strconv"
var f64 float64 = 123.456
s := strconv.FormatFloat(f64, 'f', -1, 64)
float32からstring
import "strconv"
var f32 float32 = 123.456
s := strconv.FormatFloat(f32, 'f', -1, 32)
文字列型から数値型
stringからint
import "strconv"
var s string = "123"
i, _ := strconv.Atoi(s)
stringからint64
import "strconv"
var s string = "123"
i64, _ := strconv.ParseInt(s, 10, 64)
stringからint32
import "strconv"
var s string = "123"
i32, _ := strconv.ParseInt(s, 10, 32)
stringからuint64
import "strconv"
var s string = "123"
ui64, _ := strconv.ParseUint(s, 10, 64)
stringからuint32
import "strconv"
var s string = "123"
ui32, _ := strconv.ParseUint(s, 10, 32)
stringからfloat64
import "strconv"
var s string = "123.456"
f64, _ := strconv.ParseFloat(s, 64)
stringからfloat32
import "strconv"
var s string = "123.456"
f32, _ := strconv.ParseFloat(s, 32)
論理値型から文字列型
最後に論理値型と文字列型の変換についてです。
こちらはそこまでパターンが無いと思いますが、一応まとめておきます。
boolからstring
import "strconv"
var b bool = true
s := strconv.FormatBool(b)
文字列型から論理値型
stringからbool
import "strconv"
var s string = "true"
b, _ := strconv.ParseBool(s)
まとめ
今回はGo言語における型変換(キャスト)の方法についてまとめてみました。
Go言語のキャスト方法は他言語と違い容易に変更できないようにしているのか、とても覚えきれません。
おそらく私自身も実装の度に今回の記事に戻ってきて、参照するような気がしています。
正確に型を意識して実装することで予期せぬエラーを無くすことは可能だとは思いますが、実装工数との比較的にはどっちがいいか判断するのは難しいと思いますね。
ですので、JSのstrictモードとそうじゃないモードみたいなのがGo言語でもあると個人的にはすごい助かるなと思いました。
Goの融通が利かない型の扱いについてチートシート的な役割になれば幸いです。
コメント