Goでは、実行時にその型からオブジェクトのインスタンスを作成するにはどうすればよいですか?私はあなたも最初のオブジェクトの実際type
を取得する必要があると思いますか?実行時に、その型から構造体の新しいインスタンスを作成するにはどうすればよいですか?
メモリを節約するために遅延インスタンス化を実行しようとしています。
Goでは、実行時にその型からオブジェクトのインスタンスを作成するにはどうすればよいですか?私はあなたも最初のオブジェクトの実際type
を取得する必要があると思いますか?実行時に、その型から構造体の新しいインスタンスを作成するにはどうすればよいですか?
メモリを節約するために遅延インスタンス化を実行しようとしています。
これを行うには、reflect
が必要です。
package main
import (
"fmt"
"reflect"
)
func main() {
// one way is to have a value of the type you want already
a := 1
// reflect.New works kind of like the built-in function new
// We'll get a reflected pointer to a new int value
intPtr := reflect.New(reflect.TypeOf(a))
// Just to prove it
b := intPtr.Elem().Interface().(int)
// Prints 0
fmt.Println(b)
// We can also use reflect.New without having a value of the type
var nilInt *int
intType := reflect.TypeOf(nilInt).Elem()
intPtr2 := reflect.New(intType)
// Same as above
c := intPtr2.Elem().Interface().(int)
// Prints 0 again
fmt.Println(c)
}
int型ではなくstruct型でも同じことができます。それとも何か、本当に。地図とスライスのタイプについては、newとmakeの区別を必ず確認してください。
reflect.Zero()
は、struct型のゼロ値の表現を返します。後者は、動的構造体を割り当て、あなたにポインタを与えるよう(あなたがvar foo StructType
をした場合と同様に)これはreflect.New
は自動的に構造体の分野で使用される参照タイプを作成していないとして、あなたは可能性がnew(StructType)
と同様に、reflect.New()
異なっています
package main
import (
"fmt"
"reflect"
)
type Config struct {
Name string
Meta struct {
Desc string
Properties map[string]string
Users []string
}
}
func initializeStruct(t reflect.Type, v reflect.Value) {
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
ft := t.Field(i)
switch ft.Type.Kind() {
case reflect.Map:
f.Set(reflect.MakeMap(ft.Type))
case reflect.Slice:
f.Set(reflect.MakeSlice(ft.Type, 0, 0))
case reflect.Chan:
f.Set(reflect.MakeChan(ft.Type, 0))
case reflect.Struct:
initializeStruct(ft.Type, f)
case reflect.Ptr:
fv := reflect.New(ft.Type.Elem())
initializeStruct(ft.Type.Elem(), fv.Elem())
f.Set(fv)
default:
}
}
}
func main() {
t := reflect.TypeOf(Config{})
v := reflect.New(t)
initializeStruct(t, v.Elem())
c := v.Interface().(*Config)
c.Meta.Properties["color"] = "red" // map was already made!
c.Meta.Users = append(c.Meta.Users, "srid") // so was the slice.
fmt.Println(v.Interface())
}
ここエヴァンショーが与えたような基本的な例ですが、構造体を持つ:
package main
import (
"fmt"
"reflect"
)
func main() {
type Product struct {
Name string
Price string
}
var product Product
productType := reflect.TypeOf(product) // this type of this variable is reflect.Type
productPointer := reflect.New(productType) // this type of this variable is reflect.Value.
productValue := productPointer.Elem() // this type of this variable is reflect.Value.
productInterface := productValue.Interface() // this type of this variable is interface{}
product2 := productInterface.(Product) // this type of this variable is product
product2.Name = "Toothbrush"
product2.Price = "2.50"
fmt.Println(product2.Name)
fmt.Println(product2.Price)
}
再帰的にこれらのフィールドタイプを(この例では、再帰的な構造体の定義に注意)初期化するには、次のようなものを使用Reflect.zeroを使用してnewacctの応答パー
が、それは次のようになります。外出先での反射の基礎に
var product Product
productType := reflect.TypeOf(product) // this type of this variable is reflect.Type
productValue := reflect.Zero(productType) // this type of this variable is reflect.Value
productInterface := productValue.Interface() // this type of this variable is interface{}
product2 := productInterface.(Product) // the type of this variable is Product
は、 –