Golang接口结构

新手上路,请多包涵

我有一个函数,它有一个类型为 interface{} 的参数,例如:

 func LoadTemplate(templateData interface{}) {

在我的例子中,templateData 是一个结构,但每次它都有不同的结构。我使用了“interface{}”类型,因为它允许我发送所有类型的数据。

我正在使用此 templateData 将数据发送到模板:

 err := tmpl.ExecuteTemplate(w, baseTemplateName, templateData)

但现在我想添加一些新数据,但我不知道该怎么做,因为“接口”类型不允许我添加/添加任何内容。

我试图将接口转换为结构,但我不知道如何将数据附加到具有未知结构的结构。

如果我使用以下函数,我可以看到接口的数据:

 templateData = appendAssetsToTemplateData(templateData)

func appendAssetsToTemplateData(t interface{}) interface{} {
    switch reflect.TypeOf(t).Kind() {
    case reflect.Struct:
        fmt.Println("struct")
        s := reflect.ValueOf(t)
        fmt.Println(s)

        //create a new struct based on current interface data
    }

    return t
}

知道如何将子项附加到初始接口参数(templateData)吗?或者我如何将它转换为结构或其他东西以附加新的子/数据?

原文由 Pascut 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 396
2 个回答

阿德里安是对的。更进一步,如果您知道实现该接口的类型,则只能对接口执行任何操作。空接口 interface{} 并不是通常被误解的“任何”值;它只是一个所有类型都能立即满足的接口。

因此,你只能通过知道满足空接口前后的类型,从中获取值或者创建一个新的具有添加值的“接口”。

在给定静态类型的情况下,最接近做你想做的事情是将之前的类型嵌入到之后的类型中,这样仍然可以在之后的类型的根部访问所有内容。以下说明了这一点。

https://play.golang.org/p/JdF7Uevlqp

 package main

import (
    "fmt"
)

type Before struct {
    m map[string]string
}

type After struct {
    Before
    s []string
}

func contrivedAfter(b interface{}) interface{} {
    return After{b.(Before), []string{"new value"}}
}

func main() {
    b := Before{map[string]string{"some": "value"}}
    a := contrivedAfter(b).(After)
    fmt.Println(a.m)
    fmt.Println(a.s)
}

此外,由于您传递给模板的数据不需要您指定类型,您可以使用匿名结构来完成非常相似的事情。

https://play.golang.org/p/3KUfHULR84

 package main

import (
    "fmt"
)

type Before struct {
    m map[string]string
}

func contrivedAfter(b interface{}) interface{} {
    return struct{
        Before
        s []string
    }{b.(Before), []string{"new value"}}
}

func main() {
    b := Before{map[string]string{"some": "value"}}
    a := contrivedAfter(b)
    fmt.Println(a)
}

原文由 theherk 发布,翻译遵循 CC BY-SA 3.0 许可协议

您不能将数据任意附加到结构;它们是静态类型的。您只能将值分配给为该特定结构类型定义的字段。你最好的选择可能是使用 map 而不是结构。

原文由 Adrian 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题