如何在Go中从运行时的类型创建结构的新实例?
在Go中,如何在运行时从对象的类型创建对象的实例?我想您也需要先获得对象的实际如何在Go中从运行时的类型创建结构的新实例?,go,reflection,go-reflect,Go,Reflection,Go Reflect,在Go中,如何在运行时从对象的类型创建对象的实例?我想您也需要先获得对象的实际类型 我正在尝试进行延迟实例化以节省内存。为了做到这一点,您需要反射 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
类型
我正在尝试进行延迟实例化以节省内存。为了做到这一点,您需要
反射
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或其他任何类型来做同样的事情。当涉及到映射和切片类型时,请确保知道new和make之间的区别。您可以使用
reflect.Zero()
,它将返回结构类型的零值表示形式。(类似于如果您执行了var foo StructType
)这不同于reflect.New()
,因为后者将动态分配结构并给您一个指针,类似于New(StructType)
asreflect。New
不会自动在结构字段中使用引用类型,您可以使用以下类似的方法递归初始化这些字段类型(请注意本例中的递归结构定义):
主程序包
进口(
“fmt”
“反映”
)
类型配置结构{
名称字符串
元结构{
描述字符串
属性映射[字符串]字符串
用户[]字符串
}
}
func initializeStruct(t reflect.Type,v reflect.Value){
对于i:=0;i
下面是一个基本示例,如Evan Shaw给出的示例,但有一个结构:
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)
}
根据newacct的响应,使用Reflect.zero将是:
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
关于围棋中反射的基础知识 您不需要
reflect
,如果factory模式共享相同的界面,您可以轻松实现这一点:
package main
import (
"fmt"
)
// Interface common for all classes
type MainInterface interface {
GetId() string
}
// First type of object
type FirstType struct {
Id string
}
func (ft *FirstType) GetId() string {
return ft.Id
}
// FirstType factory
func InitializeFirstType(id string) MainInterface {
return &FirstType{Id: id}
}
// Second type of object
type SecondType struct {
Id string
}
func (st *SecondType) GetId() string {
return st.Id
}
// SecondType factory
func InitializeSecondType(id string) MainInterface {
return &SecondType{Id: id}
}
func main() {
// Map of strings to factories
classes := map[string]func(string) MainInterface{
"first": InitializeFirstType,
"second": InitializeSecondType,
}
// Create a new FirstType object with value of 10 using the factory
newObject := classes["first"]("10")
// Show that we have the object correctly created
fmt.Printf("%v\n", newObject.GetId())
// Create a new SecondType object with value of 20 using the factory
newObject2 := classes["second"]("20")
// Show that we have the object correctly created
fmt.Printf("%v\n", newObject2.GetId())
}
switch ft.Type.Kind()
应该是switch ft.Kind()
?ft变量的类型是StructField,Kind()本身是reflect.Type struct中的一个方法如果有指向结构的指针呢?(&Config{}
而不是Config{}
)@Xeoncross,这在最后一个案例
中介绍,其中字段的类型与reflect.Ptr
@fuzzybear3965进行比较,谢谢,自从我的问题发布后,答案已更新。下面是结构的答案版本。我是否必须基于某个对象或指向该对象的指针对其进行实例化?我正在使用struct。我希望它获取结构本身(不是它的实例化对象),获取它的类型,并使用反射实例化它。或者,我想以某种方式使用reflect.New(something)实例化一个对象,而不只是以通常的方式实例化结构,因为应该从函数参数向代码中传递某些内容。我该怎么做呢?product2:=productInterface.(Product)的意义是什么?当一个人可以product2:=Product{}时,问题是如果不键入Product,我就无法将json.Unmarshal转换为这样的值。所以对于json包来说,这似乎毫无意义。
package main
import (
"fmt"
)
// Interface common for all classes
type MainInterface interface {
GetId() string
}
// First type of object
type FirstType struct {
Id string
}
func (ft *FirstType) GetId() string {
return ft.Id
}
// FirstType factory
func InitializeFirstType(id string) MainInterface {
return &FirstType{Id: id}
}
// Second type of object
type SecondType struct {
Id string
}
func (st *SecondType) GetId() string {
return st.Id
}
// SecondType factory
func InitializeSecondType(id string) MainInterface {
return &SecondType{Id: id}
}
func main() {
// Map of strings to factories
classes := map[string]func(string) MainInterface{
"first": InitializeFirstType,
"second": InitializeSecondType,
}
// Create a new FirstType object with value of 10 using the factory
newObject := classes["first"]("10")
// Show that we have the object correctly created
fmt.Printf("%v\n", newObject.GetId())
// Create a new SecondType object with value of 20 using the factory
newObject2 := classes["second"]("20")
// Show that we have the object correctly created
fmt.Printf("%v\n", newObject2.GetId())
}