登录
首页 >  Golang >  Go问答

生成可访问的getter函数来进行接口强制转换的制作方法

来源:stackoverflow

时间:2024-02-11 18:03:23 128浏览 收藏

大家好,我们又见面了啊~本文《生成可访问的getter函数来进行接口强制转换的制作方法》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~

问题内容

我有 context 的概念,它是一个可以容纳任何结构的映射。基本上,我想创建一个通用 getter,可寻址“填充”目标接口(类似于 json 解码的工作原理)。

以下是我希望其如何工作的示例:

type context map[string]interface{}

// random struct that will be saved in the context
type step struct { 
    name string
}

func main() {
    stepa := &step{name: "cool name"}

    c := context{}
    c["stepa"] = stepa

    var stepb *step
    err := c.get("stepa", stepb)
    if err != nil {
        panic(err)
    }

    fmt.println(stepb.name) // cool name
    stepb.name = "coolname2"

    fmt.println(stepa.name) // i want to say: coolname2
}

func (c context) get(stepid string, dest interface{}) error {
    context, ok := c[stepid]
    if !ok {
        return nil
    }

    destinationvalue := reflect.valueof(dest)
    contextvalue := reflect.valueof(context)

    destinationvalue.set(contextvalue) // errors here
    return nil
}

我倾向于使用反射,但也许我不需要它? - 因此接受其他建议(泛型除外,因为这会使其他问题变得复杂)我收到上述错误:

panic: reflect: reflect.Value.Set using unaddressable value

您可以在这里进行测试。


正确答案


传递给 get 的参数必须是指针类型,其元素类型与上下文映射中的类型相同。因此,如果上下文映射中的值的类型为 *step,则参数的类型必须为 **step。另外传入的参数不能是 nil,它可以是指向 nil 的指针,但它本身不能是 nil

所以在你的情况下你应该这样做:

var stepb *step
err := c.get("stepa", &stepb) // pass pointer-to-pointer
if err != nil {
    panic(err)
}

还有 get 方法,已修复一点:

func (c Context) Get(stepId string, dest interface{}) error {
    context, ok := c[stepId]
    if !ok {
        return nil
    }

    dv := reflect.ValueOf(dest)
    if dv.Kind() != reflect.Ptr || dv.IsNil() {
        return errors.New("dest must be non-nil pointer")
    }

    dv = dv.Elem()
    cv := reflect.ValueOf(context)
    if dv.Type() != cv.Type() {
        return errors.New("dest type does not match context value type")
    }

    dv.Set(cv)
    return nil
}

https://go.dev/play/p/OECttqp1aVg

今天关于《生成可访问的getter函数来进行接口强制转换的制作方法》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>