我们可以使用空接口指向的实际类型来在Go语言中创建该类型的新实例。

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

How can we use the actual type pointed to by an empty interface to create a new instance of that type in Go?

问题

请检查下面的程序。变量z的类型是interface{}。它存储了结构体X的类型。但是我无法使用它来创建X的新实例。我有一些要求,需要将对象的类型保留在interface{}变量中,并使用它来创建该类型的实例。这是一个在Go Playground上的代码片段链接

package main

import (
	"fmt"
	"reflect"
)

type X struct {
	a int
	b int
}

type MyInt int

func main() {
	x := X{}
	y := reflect.TypeOf(x)
	fmt.Printf("%v\n", reflect.New(y))

	var z interface{}
	z = y
	fmt.Printf("%v\n", z) // 打印 main.X

	// 下面的代码会抛出错误
	fmt.Printf("%v\n", reflect.New(z)) //----> 这行代码会抛出错误
}
英文:

Please check the below program. Var z is of type interface{}. It stores the type of struct X. But I cannot use it to create a new instance of X. I have some requirement where I need to keep the type of the object in an interface{} variable, and use that to create an instance of that type. Here is a link for the snippet on go playground

package main

import (
	"fmt"
	"reflect"
)

type X struct {
	a int
	b int
}

type MyInt int

func main() {
	x := X{}
	y := reflect.TypeOf(x)
	fmt.Printf("%v\n", reflect.New(y))

	var z interface{}
	z = y
	fmt.Printf("%v\n", z) // prints main.X

	//Below line throws the error
	fmt.Printf("%v\n", reflect.New(z)) //----> This line throws error

}

答案1

得分: 0

你可以使用type assertioninterface{}值中提取reflect.Type值:

fmt.Printf("%v\n", reflect.New(z.(reflect.Type))) //----> 可行!

你可以在Go Playground上查看修改后的示例。

请注意,上述示例在z不包含reflect.Type类型的值或为nil时会引发恐慌。你可以使用特殊的逗号-ok形式来防止这种情况发生:

if t, ok := z.(reflect.Type); ok {
	fmt.Printf("%v\n", reflect.New(t))    // t的类型是reflect.Type
} else {
	fmt.Println("不是预期的类型或为nil!")
}
英文:

You can use type assertion to extract the reflect.Type value from an interface{} value:

fmt.Printf("%v\n", reflect.New(z.(reflect.Type))) //----> Works!

Your modified example on the Go Playground.

Note that the above example panics if z does not hold a value of type reflect.Type or if it is nil. You can use the special comma-ok form to prevent that:

if t, ok := z.(reflect.Type); ok {
	fmt.Printf("%v\n", reflect.New(t))    // t is of type reflect.Type
} else {
	fmt.Println("Not the expected type or nil!")
}

huangapple
  • 本文由 发表于 2016年4月5日 14:22:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/36418582.html
匿名

发表评论

匿名网友

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

确定