- 全体的にGo言語の慣習に従ったシンプルな構成です。
- ファイルの存在確認・エラーハンドリングも十分です。
- 主要な関数には日本語のコメントが付いています。
- 拡張性・保守性に課題がある箇所もいくつか見受けられます(下記参照)。
- JSONファイルを読み込んでmapで返す処理で、エラーハンドリングも適切です。
- defer file.Close()の配置も問題ありません。
- map[string]interface{}なので型アサーションの際にpanicの可能性があるため注意。
- Excelワークブックの1行目をラベル、2行目以降をデータとして処理しています。
- データが不足している場合のエラー対応もあり安全です。
- 既存実装だと「ラベルとカラム数の不一致時」に記載のあるセル以降が無視されます(適正)。
- データ行のカラムがラベル数より少ない場合、結果にラベルが欠落するデータになる可能性。
- 単純ですが、必ずしもファイルのパス指定が正しくない場合は意図通り動作しない場合があるので注意が必要。
- コマンドライン引数で設定ファイル名を受け取ります(-sオプション)。
- 主要処理が直書きされているため、規模が大きくなる場合は分離を検討しましょう。
- params["xlsx_dir"].(string) のように型アサーションをしているため、configの変更や不整合でパニックとなる場合があります。
- ファイルクローズの際にエラーチェックを行っていません(defer f.Close()推奨)。
- 型アサーションのエラーチェック型が違った場合panicになるため、事前に ok を使った方が安全です。
- ファイルクローズ時のエラーチェック・deferの利用明示的なcloseをdeferに(複数exitパスあり)。
- エラー発生時に即return可能な場所でreturn判定f.Writeに失敗した際ファイルをクローズできない点。
- params.json読み込みの処理にカレントディレクトリをデフォルトで利用する注意→ getParamsのdoc強調
- コメント追加例(一部のみ)
コメント・改善提案付きサンプル
// JSONファイルを読み込み、mapで返却する関数。
// カレントディレクトリの指定ファイルを想定しています。
func getParams(filename string) (map[string]interface{}, error) {
// ファイルを開く
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
var data map[string]interface{}
// JSONをデコード
decoder := json.NewDecoder(file)
if err := decoder.Decode(&data); err != nil {
return nil, err
}
return data, nil
}
func main() {
var (
s = flag.String("s", "config.json", "設定ファイル名(json)")
)
flag.Parse()
if *s == "" {
os.Exit(1)
}
filename := *s
// 設定ファイルの存在を確認
if notExists(filepath.Join("./", filename)) {
log.Fatalf("設定ファイルが見つかりません: %s", filename)
}
params, err := getParams(filename)
if err != nil {
log.Fatalf("パラメータファイルの解析に失敗: %v", err)
}
// 型アサーション時の存在性チェックを追加
xlsxDir, ok1 := params["xlsx_dir"].(string)
xlsxWb, ok2 := params["xlsx_wb"].(string)
xlsxWs, ok3 := params["xlsx_ws"].(string)
distDir, ok4 := params["dist_dir"].(string)
if !ok1 || !ok2 || !ok3 || !ok4 {
log.Fatalf("設定ファイルに必要なキーが不足、または型が不正です")
}
filePath := filepath.Join(xlsxDir, xlsxWb)
sheetName := xlsxWs
// JSON変換を実行
jsonOutput, err := convertExcelToJSON(filePath, sheetName)
if err != nil {
log.Fatalf("Excel->JSON変換エラー: %v", err)
}
// 結果をファイルに書き込み
distPath := filepath.Join(distDir, sheetName+".json")
f, err := os.Create(distPath)
if err != nil {
log.Fatalf("ファイル作成失敗: %v", err)
}
defer f.Close() // 明示的にdeferへ
data := []byte(jsonOutput)
count, err := f.Write(data)
if err != nil {
log.Fatalf("ファイル書き込み失敗: %v", err)
}
fmt.Printf("create %s\n", distPath)
fmt.Printf("write %d bytes\n", count)
}- 基本的な処理・エラーハンドリングは丁寧ですが、「型アサーション」「ファイルクローズ」部分などの安全対策を強化するとより堅牢です。
- コメントは概ね良いですが、上記例のように「何を意図」しているか付記すると他人(将来の自分)にも親切です。