【发布时间】:2014-08-16 20:25:39
【问题描述】:
如果我有:
type foo struct{
}
func bar(baz interface{}) {
}
以上内容一成不变 - 我无法更改 foo 或 bar。此外,baz 必须转换回 bar 内的 foo 结构指针。如何将 &foo{} 转换为 interface{} 以便在调用 bar 时将其用作参数?
【问题讨论】:
标签: pointers struct interface go
如果我有:
type foo struct{
}
func bar(baz interface{}) {
}
以上内容一成不变 - 我无法更改 foo 或 bar。此外,baz 必须转换回 bar 内的 foo 结构指针。如何将 &foo{} 转换为 interface{} 以便在调用 bar 时将其用作参数?
【问题讨论】:
标签: pointers struct interface go
将*foo 变成interface{} 很简单:
f := &foo{}
bar(f) // every type implements interface{}. Nothing special required
要返回*foo,您可以执行type assertion:
func bar(baz interface{}) {
f, ok := baz.(*foo)
if !ok {
// baz was not of type *foo. The assertion failed
}
// f is of type *foo
}
或type switch(类似,但如果baz 可以是多种类型,则很有用):
func bar(baz interface{}) {
switch f := baz.(type) {
case *foo: // f is of type *foo
default: // f is some other type
}
}
【讨论】:
baz 在你的例子中
baz 可能是哪种类型,那么您将不得不使用反射 (import "reflect")。这就是像encoding/json 这样的包在事先不知道的情况下基本上可以编码任何类型的方式。
fmt.Printf 将始终将其参数作为接口接收。它的作用是告诉您接口inside 的类型。这意味着fmt.Printf("%T", f) 和fmt.Printf("%T", interface{}(f)) 是相同的。唯一不同的是,在后者中,我做了一个冗余的显式转换。
不完全相关,但我用谷歌搜索了“将接口结构转换为指针”的问题并到达这里。
所以,请注意:将interface of T 转换为interface of *T:
//
// Return a pointer to the supplied struct via interface{}
//
func to_struct_ptr(obj interface{}) interface{} {
vp := reflect.New(reflect.TypeOf(obj))
vp.Elem().Set(reflect.ValueOf(obj))
return vp.Interface()
}
【讨论】:
使用反射
reflect.ValueOf(myStruct).Interface().(newType)
【讨论】:
reflect 可以做到这一点,但这是一种繁重而危险的转换方式。在接受的答案中描述了一种更简单的方法。
可以像这样实现将结构转换为接口。 其中 i 是分配数据结构。
var j 接口{} = &i
【讨论】: