LoginSignup
3
3

More than 1 year has passed since last update.

【Go】reflectを使用した型判定で`reflect.Type`に無いものも使用したい

Posted at

概要

あまり使うことは多くないと思いますが、例えばStructのフィールドを動的に取得する等の際に、reflectパッケージを利用します。reflectの概要等は、reflectで動的に型を判定の記事にまとめられています。
上記で紹介した記事ではreflect.Typeを使用して型の判定を行なっていますが、例えばtime.Time型などreflect.Typeに用意されていない型が含まれる時にどうするか。対応方法をメモ書きします。

対応

Go type switch with time.Timeのstackoverflowの記事にいくつか対応方法が紹介されています。
個人的には一度Interface型でreflectのvalueを取得した後に、型の判定をする方法が良いかなと感じました。

実装サンプル

Interface型でreflectのvalueを取得した後に、型の判定をする実装サンプルを以下に記します。

package main

import (
	"fmt"
	"reflect"
	"time"
)

type ReflectSampleStruct struct {
	IntSample    int
	StringSample string
	DateSample   time.Time
}

func main() {
	reflectSample := ReflectSampleStruct{
		IntSample:    100,
		StringSample: "sample",
		DateSample:   time.Now(),
	}
	reflectValue := reflect.ValueOf(reflectSample)
	reflectType := reflect.TypeOf(reflectSample)
	fieldLen := reflectType.NumField()
	for i := 0; i < fieldLen; i++ {
		field := reflectType.Field(i)
		value := reflectValue.FieldByName(field.Name)
		// 一度Interface型で取得する
		valueInterface := value.Interface()
		switch v := valueInterface.(type) {
		case int:
			fmt.Println("【int】")
			fmt.Println(v)
		case string:
			fmt.Println("【string】")
			fmt.Println(v)
		case time.Time:
			fmt.Println("【time.Time】")
			fmt.Printf("%d/%d/%d", v.Year(), v.Month(), v.Day())
		}
	}
}
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3