🦫
Go1.22のリリースで本業で即利用できそうなものをまとめてみた
本業でGoを使っており、備忘録として、Go1.22で導入された新しい機能のうちすぐに利用できそうなものをまとめた。
TL;DR
-
database/sql
のNull[T]
は独自で型定義しているとき、Scan
などの実装をスキップできる -
slices
のConcat
database/sql
の Null[T]
1. 独自の型を定義をしている場合以下のように読み取り( Scan
)と書き込み( Value
)用の実装することがある
type Email string
func (e *Email) Validate() error {
r, err := regexp.Compile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
if err != nil {
return err
}
if !r.MatchString(string(*e)) {
return errors.New("invalid email")
}
return nil
}
func (e *Email) Scan(value any) error {
switch t := value.(type) {
case string:
*e = Email(t)
return e.Validate()
case []byte:
*e = Email(t)
return e.Validate()
}
return errors.New("invalid type")
}
func (e Email) Value() (driver.Value, error) {
return string(e), nil
}
このとき、emailのカラムがDBでNULL許容なカラム立った場合、以前までは以下のようにする必要があった。
func (e *NullEmail) Scan(value any) error {
if value == nil {
e.Email, e.Valid = "", false
return nil
}
e.Valid = true
return e.Email.Scan(value)
}
func (e NullEmail) Value() (driver.Value, error) {
if !e.Valid {
return nil, nil
}
return e.Email.Value()
}
これが自前で実装の必要がなく、以下のようにするだけでよくなった。
type User struct {
// 以下のように利用箇所で定義するだけ
Email sql.Null[Email]
}
slices
の Concat
2. これはかなりシンプルで2つ以上の配列から、一つの配列を作るもの。
これまでは以下のようにちょっと気持ち悪い感じのコードを書いていた。
arr1 := []string{"a", "b", "c"}
arr2 := []string{"d", "e", "f"}
arr3 := []string{"g", "h", "i"}
arr := append(arr1, append(arr2, arr3...)...) // arr = [a b c d e f g h i]
これが以下だけでよくなります。
arr1 := []string{"a", "b", "c"}
arr2 := []string{"d", "e", "f"}
arr3 := []string{"g", "h", "i"}
arr = slices.Concat(arr1, arr2, arr3) // arr = [a b c d e f g h i]
slices.Concat の内部的には、slices.Grow を使っていて、渡された引数のSliceの長さを計算して、必要な分だけメモリを確保しているためメモリ効率も良い。
所感
今回まとめた2つのうち特に Null[T]
はすでにこれを使わずに実装している部分があり、そのコードが不要になりそうなので、リファクタリングしたいと思っている。
今回追加にはならなかったが、range over funcは気になる。習得したらプログラムの書き方を大幅にアップデートできそうな気がするので早めにキャッチアップしていきたい。一方でGoの良さの一つであるシンプルさが失われないかどうかは確認しておきたい。
Discussion