Golang接口到struct

Pas*_*cut 7 struct interface go

我有一个函数,其参数类型为interface {},如下所示:

func LoadTemplate(templateData interface{}) {
Run Code Online (Sandbox Code Playgroud)

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

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

err := tmpl.ExecuteTemplate(w, baseTemplateName, templateData)
Run Code Online (Sandbox Code Playgroud)

但是现在我想添加一些新数据,我不知道怎么做,因为"interface"类型不允许我添加/追加任何东西.

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

如果我使用以下功能,我可以看到界面的数据:

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
}
Run Code Online (Sandbox Code Playgroud)

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

The*_*erk 12

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

因此,您只能通过在添加之前和之后知道满足空接口的类型来从中获取值或创建具有添加值的新"接口".

在静态类型中,最接近你可以做到你想要的是通过在after类型中嵌入before类型,以便仍然可以在after类型的根处访问所有内容.以下说明了这一点.

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)
}
Run Code Online (Sandbox Code Playgroud)

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

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)
}
Run Code Online (Sandbox Code Playgroud)

  • 这些例子帮助我解决了这个问题.谢谢. (2认同)