数値 (int) → 文字列 (string)
var i int = 123
var toString string
toString = strconv.Itoa(i) // "123"
toString = string(i) // 123がrune(Unicode)として認識され "{" になるので注意!!
Unicode 123(10進数)は {
参考 : https://www.codetable.net/decimal/123
文字列 (String) → 数値 (Int)
var s string = "123"
var s2 string = "Doraemon"
var toInt int
toInt, _ = strconv.Atoi(s)
fmt.Println(toInt) // 123
var err error
toInt, err = strconv.Atoi(s2) // panicにはならないが、toIntにはゼロ値、errにはエラーメッセージを返す。
fmt.Println(toInt) // 0
fmt.Println(err) // strconv.Atoi: parsing "Doraemon": invalid syntax
文字列 (string) → 論理型 (bool)
var s string = "true"
var toBool bool
toBool, _ = strconv.ParseBool(s)
fmt.Println(toBool) // true
-
ParseBool
で変換できる文字列- true : "1", "t", "T", "true", "TRUE", "True"
- false : "0", "f", "F", "false", "FALSE", "False"
論理型 (bool) → 文字列 (string)
var b bool = false
var toString string
toString = strconv.FormatBool(b)
fmt.Println(toString) // "false"
Interface{}の変換
interface{}にはどんな型でも入れるのが可能。
ただし、入れた値そのままでは元の型としての処理はできないので、.(元の型)
で明示してからは可能になる。
type Robot struct {
name string
birth int
}
func main() {
dora := Robot{
name: "Doraemon",
birth: 2112,
}
Anything := map[string]interface{}{
"valString": "文字列",
"valInt": 1234,
"valBool": true,
"valStruct": dora, // Robot (struct)
}
}
var stringValue string
var intValue int
var boolValue bool
var structValue Robot
// エラーのパターン
Anything["valInt"]++
// invalid operation: Anything["valInt"]++ (non-numeric type interface {})
stringValue = Anything["valString"]
// cannot use Anything["valString"] (type interface {}) as type string in assignment: need type assertion
name := Anything["valStruct"].name
// Anything["valStruct"].name undefined (type interface {} is interface with no methods
// 正常のパターン
Anything["valInt"] = Anything["valInt"].(int) + 1
stringValue = Anything["valString"].(string)
name := Anything["valStruct"].(Robot).name // "Doraemon"
interface{}から型を明示して取り出すときは元の型ではないとエラーになる。(暗黙的な変換はできない)
// panic
name := Anything["valInt"].(string)
// panic: interface conversion: interface {} is int, not string
// 正常 (元の型を明示して出したあとに型変換する。)
name := strconv.Itoa(Anything["valInt"].(int)) // "1234"
map[string]interface{}の for range
mapの値をinterface{}
にしたら、どの型とでもいれられるが、rangeで回すときは内部で適切な処理のためには値の本当の型を判別し、変換が必要になる。
Type switchを使うと便利。(参考 : A Tour of Go - Type switches)
var intValue int
...
for i, v := range Anything {
switch v := v.(type) { // 元の型キャストされる (switchのスコープ内のみ)
case int:
intValue = v
fmt.Printf("%s:%d (%T)\n", i, v, v) // valInt:1234 (int)
case string:
fmt.Printf("%s:%s (%T)\n", i, v, v) // valString:文字列 (string)
case bool:
fmt.Printf("%s:%t (%T)\n", i, v, v) // valBool:true (bool)
case Robot:
fmt.Printf("%s: %+v (%T)\n", i, v, v) // valStruct: {name:Doraemon birth:2112} (main.Robot)
...
}
}