英文:
Go: Passing a return value via an interface{} pointer
问题
我有一个函数,看起来像这样:
func Foo(result interface{}) error {
...
json.Unmarshal([]byte(some_string), result)
...
}
它的调用方式如下:
var bar Bar
Foo(&bar)
通常情况下,Foo会获取一个字符串,然后将其解析为结果。然而,现在我需要更新它,使得Foo有时从另一个来源加载数据并返回。
type Loader func() interface{}
func Foo(result interface{}, load Loader) error {
...
data := load()
// result = data ???
...
}
有没有办法将这个新值赋给result?我发现我可以将数据编组为字符串,然后将其解组到result中,这样可以工作,但我无法想象这是最好的方法。
英文:
I have a function that looks like this:
func Foo(result interface{}) error {
...
json.Unmarshal([]byte(some_string), result)
...
}
Which is called like this:
var bar Bar
Foo(&bar)
Generally, Foo fetches a string that is then unmarshalled into the result. However, now I need to update it so that Foo sometimes loads data from another source and returns that instead.
type Loader func() (interface{})
func Foo(result interface{}, Loader load) error {
...
data := load()
// result = data ???
...
}
Is there any way for me to assign this new value to result? I found that I can marshal the data into a string and then unmarshal it into result which works, but I can't imagine that's the best way.
答案1
得分: 5
你可以这样做:
p := result.(*Bar)
*p = data
第一行是一个类型断言(type assertion)。
第二行将data
赋值给解引用的指针。将值赋给解引用的指针会改变引用地址处的值。
由于你不知道result
或data
的底层类型,你最好使用类型断言的switch语句。
switch v := data.(type) {
case Bar:
// 如果'data'的类型是'Bar'
p, ok := result.(*Bar)
if !ok {
// 这意味着输入有误。
// 'result'和'data'应该具有相同的底层类型。
fmt.Println("底层类型不匹配")
break
}
*p = v
case Baz:
// 如果'data'的类型是'Baz'
// 对于'Baz',与上面的代码等效
}
参见switch语句中的**类型开关(Type Switches)**部分。
英文:
You can do,
p := result.(*Bar)
*p = data
The first line is a type assertion.
The second assigns data
to the dereferenced pointer. Assigning a value to a dereferenced pointer changes the value at the referenced address.
Since you don't know the underlying types of result
or data
the best you can do is using a type assertion switch.
switch v := data.(type) {
case Bar:
// If 'data' is of type 'Bar'
p, ok := result.(*Bar)
if(!ok){
// This means inputs were bad.
// 'result' and 'data' should both have the same underlying type.
fmt.Println("underlying types mismatch")
break;
}
*p = v
case Baz:
// If 'data' is of type 'Baz'
// Equivalent of above for 'Baz'
}
See Type Switches from switch statement
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论