如何将一个 interface{} 作为特定结构体传递给函数?

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

How do I pass in an interface{} to a function as a specific structure?

问题

我正在尝试使用通用的例程处理特定组件之间的消息。其中一部分涉及读取字节数组并使用json.Marshal和json.Unmarshal以及调用回调函数。

我试图将一个接口传递给一个期望特定结构的函数,但我不知道目标结构的类型。在下面的代码中,函数r()如何调用函数cb()并传递正确的数据?

package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

type Bottom struct {
	Foo string
}

func cb(b *Bottom) {

	fmt.Println("5. ", b)
}

func r(t interface{}, buf []byte) {

	_ = json.Unmarshal(buf, &t)

	fmt.Println("2. ", reflect.TypeOf(t))
	fmt.Println("3. ", t)

	cb(&t)
}

func main() {
	x := Bottom{Foo: "blah"}
	var y Bottom

	buf, _ := json.Marshal(x)

	fmt.Println("1. ", x)
	r(&y, buf)
}
英文:

I am trying to have a generic routine handle messages between specific components. Part of this involves reading a byte array and using json.Marshal and json.Unmarshal and calling a callback.

I am trying to pass an interface to a function who expects a specific structure, but I do not know the type of the target structure. In the code below, how does function r() call function cb() and pass in the correct data?

package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

type Bottom struct {
	Foo string
}

func cb(b *Bottom) {

	fmt.Println("5. ", b)
}

func r(t interface{}, buf []byte) {

	_ = json.Unmarshal(buf, &t)

	fmt.Println("2. ", reflect.TypeOf(t))
	fmt.Println("3. ", t)

	cb(&t)
}

func main() {
	x := Bottom{Foo: "blah"}
	var y Bottom

	buf, _ := json.Marshal(x)

	fmt.Println("1. ", x)
	r(&y, buf)
}

答案1

得分: 2

你需要使用类型断言来将interface{}转换为函数所需的类型。然后,你可以添加错误检查来处理参数无法转换为所需类型的情况。

在这个示例中,你可以这样写:

cb(&t.(Bottom))

你可以添加错误检查:

bottom, ok := t.(Bottom)
if !ok {
  // 处理错误情况
}
cb(&bottom)

你可以参考这个示例来了解解决方案:http://play.golang.org/p/NYeoAVTEeA

英文:

You will need to use a type assertion to convert your interface{} to the type that your function requires. You can then add error checking to appropriately handle the case where your parameter can't be typecast to the desired type.

See this generic playground that demonstrates the solution: http://play.golang.org/p/NYeoAVTEeA

In your case, that means

cb(&t.(Bottom))

You can add error checking:

bottom, ok := t.(Bottom)
if !ok {
  // do something
}
cb(&bottom)

huangapple
  • 本文由 发表于 2015年6月3日 04:19:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/30605811.html
匿名

发表评论

匿名网友

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

确定