はじめに
javaやCでは普通にできたが、Goで同じ操作をしようとしたらつまづいたので共有しておきます。Goで文字列を1文字ずつ処理する方法としてfor range
とSplit()
について紹介します。今回のプログラムは標準入力した文字列を一文字ずつ取り出し、その文字の型も追加して出力するというものです。
対象読者
Goを始めて1ヶ月未満の方
Goの文字列操作があいまいな方
その他Goの文法に自信がない方
for range
で処理する。
文字数分だけ勝手にループしてくれます。
func Range(input string){
for _, c := range input {
fmt.Printf("%c ", c)
fmt.Println(reflect.TypeOf(c))
}
fmt.Println("")
}
Split()
で処理する。
stringsパッケージのSplit関数を用いて、スライスに1文字ずつ格納していきます。
import "strings"
func Split(input string){
slice := strings.Split(input, "")
len := len(slice)
for i := 0; i < len; i++ {
fmt.Printf("%s ", slice[i])
fmt.Println(reflect.TypeOf(slice[i]))
}
fmt.Println("")
}
スライスではなく配列に格納しようとするとコンパイルエラーが起きました。
cannot use strings.Split(input, "") (type []string) as type [5]string in assignment
これはSplit()
の返り値の型がスライスだからです。javaやCでは配列が返されるので、勘違いしてました。
実行結果
実行結果の前にコード全体を載せておきます。
package main
import (
"fmt"
"strings"
"reflect"//取り出した文字の型を調べるためにimport
)
func main() {
var input string
fmt.Scan(&input)//標準入力で文字列を受け取る
fmt.Println("Range...")
Range(input)
fmt.Println("Split...")
Split(input)
}
func Range(input string){
for _, c := range input {
fmt.Printf("%c ", c)
fmt.Println(reflect.TypeOf(c))//取り出した文字の型を示す。
}
fmt.Println("")
}
func Split(input string){
slice := strings.Split(input, "")
len := len(slice)
for i := 0; i < len; i++ {
fmt.Printf("%s ", slice[i])
fmt.Println(reflect.TypeOf(slice[i]))//取り出した文字の型を示す。
}
fmt.Println("")
}
実行結果
入力した値 input = "12abCDあい"
Range...
1 int32
2 int32
a int32
b int32
C int32
D int32
あ int32
い int32
Split...
1 string
2 string
a string
b string
C string
D string
あ string
い string
for range
で取り出された文字はint32型であり、Split()
だとstring型
でした。
最後に
for range
もSplit()
も文字列にスペースが含まれるとそれ以降の文字は処理されないので注意。次回は文字列から一文字ずつ取り出し数字だったら足し、それ以外だったら足さないというプログラムを用いて、型のキャストや、スライスの扱い方にも触れながら、もう少し複雑な処理についてやってみます。