如何取消引用作为空接口传递的指针值?

m90*_*m90 4 pointers interface go

我有一种方法采用一种target interface{}我用于数据库访问的类型,例如:

func (c *client) Query(query someType, target interface{}) error {
    return c.db.Query(query).Decode(target)
}
Run Code Online (Sandbox Code Playgroud)

这然后被称为

result := resultType{}
if err := c.Query(myQuery, &result); err == nil {
    // do sth with result
}
Run Code Online (Sandbox Code Playgroud)

当我传递的指针地址 result

我现在遇到的问题是我不知道如何在测试中模拟这种行为(改变传递的引用)。

如果我不需要通过,interface{}我可以想象它是这样完成的:

type mockClient struct {
    targetValue resultType
}

func (m *mockClient) Query(query someType, target *resultType) error {
    *target = m.targetValue
    return nil
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用我的实际签名来做同样的事情,我无法target像这样取消引用包含的值:

type mockClient struct {
    targetValue interface{}
}

func (m *mockClient) Query(query someType, target interface{}) error {
    target = m.targetValue // this does not mutate the passed target
    return nil
} 
Run Code Online (Sandbox Code Playgroud)

当一个指针值作为空接口传入时,我可以取消引用它吗?万一这是不可能的,测试我的方法的副作用而不必求助于具体类型作为参数的另一种方法是什么?

Pav*_*kov 9

您可以使用 'reflect' 包来做到这一点。

package main

import (
    "fmt"
    "reflect"
)

type mockClient struct {}

func (m *mockClient) Query(query string, target interface{}) error {
    a := "changed"
    va := reflect.ValueOf(a)
    reflect.ValueOf(target).Elem().Set(va)
    return nil
}

func main() {
    var mc mockClient
    target := "initial"
    mc.Query("qwe", &target)
    fmt.Println(target)
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到要参考的简单示例