创建一个新的对象,知道反射类型。

huangapple go评论82阅读模式
英文:

Create new object knowing reflected type

问题

在函数中,我正在传递一个参数:

reflect.TypeOf(Person)

其中Person是一个带有几个字符串的结构体。如果另一个函数接受这个参数,我想要实例化这个空的结构体,知道它的反射类型。

我尝试了以下代码:

ins := reflect.New(typ)  //typ是通过reflect.TypeOf(Person)传递的类型

但是这个代码返回了nil。我做错了什么?

英文:

In function, one of arguments I'm passing

reflect.TypeOf(Person)

where person is struct with few strings. If another function which accepts this argument, I want to instantiate this empty struct knowing its reflected type.

I have tried following

ins := reflect.New(typ)  //typ is name or passed reflect.TypeOf(Person)

But this returns me nil. What am I doing wrong?

答案1

得分: 2

要告诉你做错了什么,我们需要看到更多的代码。但这是一个简单的例子,展示了如何实现你想要的功能:

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{}

    p2 := create(reflect.TypeOf(p))

    p3 := p2.(*Person)
    p3.Name = "Bob"
    p3.Age = 20
    fmt.Printf("%+v", p3)
}

func create(t reflect.Type) interface{} {
    p := reflect.New(t)
    fmt.Printf("%v\n", p)

    pi := p.Interface()
    fmt.Printf("%T\n", pi)
    fmt.Printf("%+v\n", pi)

    return pi
}

输出结果(Go Playground):

<*main.Person Value>
*main.Person
&{Name: Age:0}
&{Name:Bob Age:20}

reflect.New() 返回一个 reflect.Value 的值。返回的 Value 表示指向指定类型的新零值的指针。

你可以使用 Value.Interface() 提取指针。

Value.Interface() 返回一个类型为 interface{} 的值。显然它不能返回任何具体类型,只能返回通用的空接口。空接口不是一个 struct,所以你不能引用任何字段。但它可能(在你的情况下确实如此)保存一个 *Person 的值。你可以使用类型断言来获取类型为 *Person 的值。

英文:

To tell what you're doing wrong we should see more of your code. But this is a simple example how to do what you want:

type Person struct {
	Name string
	Age  int
}

func main() {
	p := Person{}

	p2 := create(reflect.TypeOf(p))

	p3 := p2.(*Person)
	p3.Name = &quot;Bob&quot;
	p3.Age = 20
	fmt.Printf(&quot;%+v&quot;, p3)
}

func create(t reflect.Type) interface{} {
	p := reflect.New(t)
	fmt.Printf(&quot;%v\n&quot;, p)

	pi := p.Interface()
	fmt.Printf(&quot;%T\n&quot;, pi)
	fmt.Printf(&quot;%+v\n&quot;, pi)

	return pi
}

Output (Go Playground):

&lt;*main.Person Value&gt;
*main.Person
&amp;{Name: Age:0}
&amp;{Name:Bob Age:20}

reflect.New() returns a value of reflect.Value. The returned Value represents a pointer to a new zero value for the specified type.

You can use Value.Interface() to extract the pointer.

Value.Interface() returns a value of type interface{}. Obviously it can't return any concrete type, just the general empty interface. The empty interface is not a struct, so you can't refer to any field. But it may (and in your case it does) hold a value of *Person. You can use Type assertion to obtain a value of type *Person.

huangapple
  • 本文由 发表于 2015年6月4日 13:58:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/30636022.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定