型変換
code:go
📊 1. 整数型のサイズについて
Goの整数型一覧
int // 環境依存(32bit環境なら32bit、64bit環境なら64bit)
int8 // -128 〜 127
int16 // -32,768 〜 32,767
int32 // -2,147,483,648 〜 2,147,483,647
int64 // -9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807
なぜint32を使うのか?
データベースの型と一致させるため:
-- PostgreSQLの型
INTEGER → Go: int32
BIGINT → Go: int64
SMALLINT → Go: int16
-- master_booksテーブル
total_page INTEGER → だからint32を使う
具体例:
// ❌ 型が合わない
TotalPages int // Goのデフォルトint(64bit環境では64bit)
↓
total_page INTEGER // DBは32bit
// ✅ 型が一致
TotalPages int → int32(TotalPages) → total_page INTEGER
🕐 2. sql.Nulltime.Timeについて
NULLとは?
データベースでは「値が存在しない」を表す特別な値。
-- 例:出版日が未定の本
published_at = NULL -- 「まだ決まってない」という意味
Goでの問題
// Goにはnilはあるが、time.Timeにnilは代入できない
var publishedAt time.Time = nil // ❌ エラー!
// だから特別な型が必要
var publishedAt sql.Nulltime.Time // ✅ NULLを扱える
sql.NullTの構造
type NullT any struct {
V T // 実際の値(Value)
Valid bool // 値が有効かどうか
}
// 使用例
// 値がある場合
publishedAt := sql.Nulltime.Time{
V: time.Now(), // 実際の時刻
Valid: true, // 有効な値
}
// 値がない場合(NULL)
publishedAt := sql.Nulltime.Time{
V: time.Time{}, // ゼロ値
Valid: false, // 無効=NULL
}
🔄 3. なぜ型変換が必要なのか?
3つの世界の型の違い
1. ユーザー入力の世界(Input)
- シンプルな型を使う
- "2024-01-01" → time.Time
- "100" → int
2. データベースの世界(Model)
- DB仕様に合わせた型
- INTEGER → int32
- TIMESTAMP NULL → sql.Nulltime.Time
3. ビジネスロジックの世界(UseCase)
- 両方をつなぐ変換処理
変換の流れ:
// Input(ユーザー入力)
TotalPages: 100 (int)
PublishedAt: "2024-01-01" (time.Time)
↓
// UseCase(変換)
int32(100)
sql.Nulltime.Time{V: publishedAt, Valid: true}
↓
// Model(DB保存)
total_page: 100 (INTEGER)
published_at: '2024-01-01' (TIMESTAMP)
📝 4. 他によくある型変換
文字列の長さ制限
// Input
Name string validate:"max=100"
// DB
name VARCHAR(100)
削除フラグ(論理削除)
// Input
// ユーザーは意識しない
// UseCase/Model
DeletedAt sql.Nulltime.Time // NULLなら未削除
価格(小数を避ける)
// Input
Price float64 // 1234.56
// Model
PriceCents int64 // 123456(セント単位で保存)
UUID/ULID
// Input
// 自動生成するのでユーザーは送らない
// Model
ID string // ULIDを生成して設定
🎯 まとめ
型変換が必要な理由:
1. データベースとGoの型が異なる
2. NULL値の扱いが異なる
3. 精度・サイズの違い
覚えておくべきこと:
- int32 = データベースのINTEGER
- int64 = データベースのBIGINT
- sql.NullT = NULL許可の型
- 変換はUseCase層で行う