カスタムタグの解析
リフレクションでタグを読み取ります
「カスタムタグの解析」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
自分でタグを読み取る
独自のタグキーを定義し、実行時にreflectパッケージで読み取ることができます。これにより、メタデータに基づくカスタム動作を構築できます。
reflect.TypeOf
reflect.TypeOfは、値を表す型情報を返します。構造体の型情報から、そのフィールドを調べることができます。
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string
}
func main() {
t := reflect.TypeOf(User{})
fmt.Println(t.Kind(), t.NumField())
}フィールドの反復処理
NumFieldとField(i)を使うと、構造体型のすべてのフィールドを順番に処理できます。
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string
Age int
}
func main() {
t := reflect.TypeOf(User{})
for i := 0; i < t.NumField(); i++ {
fmt.Println(t.Field(i).Name)
}
}フィールドタグへのアクセス
各フィールドには、型reflect.StructTagのTagがあります。.Get(key)を呼び出すと、特定のタグ値を読み取れます。
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string "label:\"Full Name\""
}
func main() {
f := reflect.TypeOf(User{}).Field(0)
fmt.Println(f.Tag.Get("label"))
}カスタムタグの定義
タグキーは自由に定義できます。ここではカスタムlabelタグを使って、各フィールドの人間が読みやすい名前を記述しています。
package main
import (
"fmt"
"reflect"
)
type Form struct {
Email string "label:\"Email Address\""
City string "label:\"City\""
}
func main() {
t := reflect.TypeOf(Form{})
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fmt.Println(f.Name, "->", f.Tag.Get("label"))
}
}オプションのタグにはTag.Lookup
Tag.Lookup(key)は値とbool値を返します。独自のタグが付いていない可能性のあるフィールドを扱うときに使用します。
package main
import (
"fmt"
"reflect"
)
type Form struct {
Email string "label:\"Email\""
Token string
}
func main() {
t := reflect.TypeOf(Form{})
for i := 0; i < t.NumField(); i++ {
v, ok := t.Field(i).Tag.Lookup("label")
fmt.Println(t.Field(i).Name, v, ok)
}
}フィールドの値も読み取る
reflect.ValueOfと型情報を組み合わせると、各フィールドのタグと現在の値の両方を読み取れます。
package main
import (
"fmt"
"reflect"
)
type Form struct {
Email string "label:\"Email\""
}
func main() {
f := Form{Email: "a@b.com"}
t := reflect.TypeOf(f)
v := reflect.ValueOf(f)
fmt.Println(t.Field(0).Tag.Get("label"), "=", v.Field(0))
}タグオプションの解析
タグ値にname,optのようなオプションを詰め込んでいる場合は、カンマを区切り文字としてstrings.Splitで自分で分割します。
package main
import (
"fmt"
"strings"
)
func main() {
tag := "name,omitempty"
parts := strings.Split(tag, ",")
fmt.Println("name:", parts[0], "opts:", parts[1:])
}小さなユースケース
ここまでの内容を組み合わせ、構造体から単純なラベルマップを作成します。UI層でフォームのラベルを表示する際に利用できます。
package main
import (
"fmt"
"reflect"
)
type Profile struct {
Name string "label:\"Your Name\""
Bio string "label:\"About You\""
}
func main() {
t := reflect.TypeOf(Profile{})
labels := map[string]string{}
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
labels[f.Name] = f.Tag.Get("label")
}
fmt.Println(labels)
}リフレクションのコスト
リフレクションは強力ですが、直接コードを記述するよりも遅く、コンパイル時のチェックを回避します。ホットループではなく、フレームワークのような機能に使用してください。
ポインタとreflect
ポインタを扱う場合は、フィールドを調べる前にreflect.TypeOf(v).Elem()を呼び出して、基になる構造体型を取得します。
package main
import (
"fmt"
"reflect"
)
type User struct {
Name string "label:\"Name\""
}
func main() {
u := &User{}
t := reflect.TypeOf(u).Elem()
fmt.Println(t.Field(0).Tag.Get("label"))
}クイックチェック
リフレクションで取得した構造体フィールドから、カスタムタグキーの値を読み取るメソッドはどれですか?
まとめ
カスタムタグの解析には次の方法を使います。
reflect.TypeOfを使ってフィールドを順番に処理しますfield.Tag.Get/Lookupでタグ値を読み取ります- 値を分割してオプションを解析します
- 強力ですが遅いため、フレームワークの機能に使用します
よくある質問
「カスタムタグの解析」レッスンは無料ですか?
はい。「カスタムタグの解析」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「カスタムタグの解析」で何を学びますか?
リフレクションでタグを読み取ります ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「カスタムタグの解析」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 構造体タグとは
- JSONタグ
- バリデーションライブラリ
- カスタムタグの解析