您至少需要知道它可能的类型。有几种情况,1.你认为你可能知道它是什么。 2. 您有可能的类型列表, 3. 您的代码对底层类型一无所知。
- 如果您认为您知道,可以使用类型断言将其转换回原始结构类型。
...
package main
import (
"fmt"
)
type MyStruct struct {
Thing string
}
func (s *MyStruct) Display() {
fmt.Println(s.Thing)
}
type Thingable interface {
Display()
}
func main() {
s := &MyStruct{
Thing: "Hello",
}
// print as MyThing
s.Display()
var thinger Thingable
thinger = s
// print as thingable interface
thinger.Display()
// convert thinger back to MyStruct
s2 := thinger.(*MyStruct) // this is "type assertion", you're asserting that thinger is a pointer to MyStruct. This will panic if thinger is not a *MyStruct
s2.Display()
}
您可以在这里看到它的实际效果:https://play.golang.org/p/rL12Lrpqsyu https://play.golang.org/p/rL12Lrpqsyu
请注意,如果您想测试类型而不因错误而惊慌,请执行以下操作s2, ok := thinger.(*MyStruct)
。如果成功则 ok 为 true,否则为 false。
- 如果您想针对多种类型测试接口变量,请使用开关:(滚动到底部)
...
package main
import (
"fmt"
"reflect"
)
type MyStruct struct {
Thing string
}
type MyStruct2 struct {
Different string
}
func (s *MyStruct) Display() {
fmt.Println(s.Thing)
}
func (s *MyStruct2) Display() {
fmt.Println(s.Different)
}
type Thingable interface {
Display()
}
func main() {
s := &MyStruct{
Thing: "Hello",
}
// print as MyThing
s.Display()
var thinger Thingable
thinger = s
// print as thingable interface
thinger.Display()
// try to identify thinger
switch t := thinger.(type) {
case *MyStruct:
fmt.Println("thinger is a *MyStruct. Thing =", t.Thing)
case *MyStruct2:
fmt.Println("thinger is a *MyStruct2. Different =", t.Different)
default:
fmt.Println("thinger is an unknown type:", reflect.TypeOf(thinger))
}
}
你可以在这里尝试一下https://play.golang.org/p/7NEbwB5j6Is https://play.golang.org/p/7NEbwB5j6Is
- 如果您确实对底层类型一无所知,则必须通过接口函数公开您需要的内容并调用它们。您很可能可以在不了解底层类型的情况下执行此操作。如果其他方法都失败,您可以使用
reflect
包来内省您的接口对象并收集有关它的信息。这就是 json 包读取 json 文本并返回填充结构的方式 - 尽管这是一个高级主题,如果您采用此方法,预计会花费大量时间。最好将反射代码隐藏在具有干净接口(即包 api)的包内。