はじめに
この夏、やっと職場へのGoのインストール許可を得られました。本業に勤しみつつ寸暇を見つけて「Webクライアント」「文字列カウンタ」「メール送信」「画像リサイザ」といった簡単なツールをGoで作成しました。小粒ながら何れも本業のWebシステムと連動して動作する立派なプロダクションツールです。
職場ではGoを頻繁に使えないため「いざツールを作るぞ!」となる都度、いろいろと思い出したり調べたりしながらコーディングしています。そこで、自分が良く使う処理のパーツとして「テキストファイル・文字列の操作」に関するものをざっくりとまとめてみました。
パーツ
type Date struct {
Year string
Month string
Day string
}
システム
GOMAXPROCSを最大CPU数に設定
runtime.GOMAXPROCS(runtime.NumCPU())
環境変数を取得
dsn := os.Getenv("GO_OCI8_CONNECT_STRING")
エラー
生成
var ErrArgSize = errors.New("Argument size error.")
スライス
追加
- 長さ(第2引数)は0で生成する。
- 追加する個数が(ある程度)わかっている場合は、キャパシティ(第3引数)に指定する。
- 内部でのメモリ操作が削減されるため。
- appendの戻り値を忘れずに。
slc := make([]int, 0, 10)
for i := 0; i < 10; i++ {
slc = append(slc, i)
}
書式化
%.2d - 数値なら2桁になるまで左ゼロ詰め。
d := fmt.Sprintf("%.2d/%.2d", 12, 3)
%s - 文字列ならそのままで。
%q - 文字列ならクォート付きで。
a := []string{"とうきょう", "とっきょ", "きょかきょく"}
s := fmt.Sprintf("%s", a)
q := fmt.Sprintf("%q", a)
%T - 値の型名を。
a := []string{"とうきょう", "とっきょ", "きょかきょく"}
t := fmt.Sprintf("%T", date)
%v - 構造体なら{値,...}の文字列で。
%+v - 構造体なら{属性名=値,...}の文字列で。
%#v - 構造体なら構造体{属性名=値,...}の文字列で。
date := &Date{Year: "2014", Month: "12", Day: "3"}
v := fmt.Sprintf("%v", date)
pv := fmt.Sprintf("%+v", date)
sv := fmt.Sprintf("%#v", date)
ファイル情報
ディレクトリ配下のファイル一覧を取得
- 取得したファイルがディレクトリだった場合、その配下は参照されない。
fis, err := ioutil.ReadDir(dirname)
ディレクトリかどうか判定
if fi.IsDir() {
ファイルの状態を確認
- ファイル存在チェックとして代用。
_, err := fi.Stat()
ファイル操作
オープン
- deferでのクローズを忘れずに。
fi, err := os.Open(filename)
if err != nil {
return err
}
defer fi.Close()
ファイルの状態を確認
- ファイル存在チェックとして代用。
_, err := os.Stat(filename)
ファイルを一行ずつ処理
scan := bufio.NewScanner(fi)
for scan.Scan() {
text := scan.Text()
// 以下、行に対する処理
fmt.Println(text)
}
if err := scan.Err(); err != nil {
return err
}
読み込み
- 全部読み込んで[]byte化するので、サイズの大きいファイルでは要注意。
b, err := ioutil.ReadFile(filename)
書き出し
b := buf.Bytes()
err := ioutil.WriteFile(filename, b, 0644)
日時
現在日時をtimeで取得
t := time.Now()
timeを文字列に変換
- "2006/01/02 15:04:05.000"はフォーマット文字列(年月日時分秒ミリ秒)。
s := t.Format("2006/01/02 15:04:05.000")
文字列をtimeに変換
- "2006/01/02"はフォーマット文字列(年月日)
t, err := time.Parse("2006/01/02", "2014/12/03")
スリープ
time.Sleep(10 * time.Second)
文字列
変換
int(整数)に変換
i, err := strconv.Atoi("12345")
[]byte(バイト配列)を変換
s := string(b)
操作
小文字化・大文字化
l := strings.ToLower("GoLang")
u := strings.ToUpper("GoLang")
部分一致
- 平仮名は1文字が3バイトなのでidxは6。
- 一致しない時のidxは-1。
idx := strings.Index("とうきょうとっきょきょかきょく", "きょ")
分割
v := strings.Split("とうきょうとっきょきょかきょく", "きょ")
トリム
s := strings.Trim("**きょ**", "*")
置換
- 第4引数にて、n<0の場合は全て置換。
s := "とうキョうとっキョキョかキョく"
r := strings.Replace(s, "キョ", "きょ", -1)
連結
a := []string{"とう","うとっ","","か","く"}
s := strings.Join(a, "きょ")
追記
buf := bytes.NewBufferString("とうきょう")
buf.WriteString("とっきょ")
buf.WriteString("きょかきょく")
// stringに変換
s := buf.String()
// []byteに変換
b := buf.Bytes()
JSON
構造体をJSONバイト配列に変換
date := &Date{Year: "2014", Month: "12", Day: "3"}
b, err := json.Marshal(date)
JSONバイト配列を構造体に変換
b := []byte(`{"Year": "2014", "Month": "12", "Day": "3"}`)
var date Date
err := json.Unmarshal(b, &date)
ハマった点
- 配列やスライスは定数として定義できません。
おわりに
2014年、日本のGo界隈は「プロダクション投入の年」として盛り上がり、一部の企業でもGoの本格投入や本番稼働が実現されています。規模は小さ過ぎますが、自分もその流れに影響を受け、その波に乗れたことを嬉しく思っています。
皆さんも出来る範囲からGoを導入して、ガンガン実績を作って行きましょう!q@w@p