我想做这样的事情:
type Struct1 struct {
var1 int
}
type i interface {
display()
}
func (s Struct1) display() {
fmt.Println(s.var1)
}
func check(i interface{}) {
i.(Struct1).display()
}
func main() {
data := struct {
int
}{
2,
}
check(interface{}(data))
}
我在外部依赖项中有一个函数,该函数接受并返回interface {}类型。该函数类型声明一个struct(比方说Struct1)。该结构具有未导出到的字段,因此我无法创建该结构的实例以传递给该函数。我知道它具有哪些字段,它们的名称和类型。是否可以发送不是可以声明为Struct1类型的Struct1类型的数据。
答案 0 :(得分:3)
您可以键入断言一个匿名结构吗?
当然可以!但是有局限性。
一些可行的方法:
声明匹配的匿名结构:
x := interface{}(struct { Count int }{Count: 5})
fmt.Printf("x's count: %d\n", x.(struct{Count int}).Count)
声明接口:
type Fooer interface {
Foo()
}
type X struct {}
func (x X) Foo() { fmt.Printf("X Fooed\n") }
func main() {
x := interface{}(struct { X }{ X{} }) // An anonymous struct which embeds X
x.(Fooer).Foo()
}
一些不起作用的东西:
使用未导出的字段从另一个程序包向匹配的匿名结构声明。
x := url.UserPassword("foo","bar")
fmt.Printf("Username: %s\n", x.(struct{username string; password string; passwordSet bool}).username)
答案 1 :(得分:0)
您无法在特定情况下尝试做什么。尽管Struct1
和您的匿名结构具有相同的布局,但它们对于Go编译器而言是不同的类型。想想时间。例如,Duration实际上只是一个int64
,但您不能互换使用它们。这是在Go中故意完成的。其他语言(例如C)允许您进行各种转换和强制转换,并且很少会出现编译器错误。已经证明这是程序员错误的根源,因此在Go中的处理方式有所不同。
为了完整起见,仍然为您提供问题的“解决方案”,以下是使用类似C的不安全强制转换将您的匿名结构转换为Struct1
的版本:
package main
import (
"fmt"
"unsafe"
)
type S struct {
i int
}
type I interface {
display()
}
func (s S) display() {
fmt.Println(s.i)
}
func check(i interface{}) {
i.(S).display()
}
func main() {
data := struct{ int }{2}
// check(data) this will not work
check(*((*S)(unsafe.Pointer(&data))))
}