我该怎么做呢?将结构作为接口发送到 func 并将其作为结构取回?

我是 golang 开发的新手,对与此问题相关的事情有一些疑问。


作为学习练习,我正在尝试创建一个简单的库来处理基于 json 的配置文件。作为用于多个应用程序的配置文件,它应该能够处理不同的参数。然后我创建了一个具有文件名和数据接口的类型结构配置。每个应用程序都有一个基于其配置需求的结构。


在下面的代码中,我将所有内容(lib 和“主代码”)放在一起,“TestData 结构”是“应用程序参数”。如果它不存在,它将设置一个默认值并创建文件,并且它正在工作。但是当我尝试读取文件时。我尝试解码json并将其放回数据接口。但它给了我一个错误,我不知道如何解决这个问题。有人可以帮忙吗?


[更新] 我之前没有放置目标代码,因为我认为将所有内容作为单个程序阅读会更容易。Bellow 是用于更好地查看问题的“目标代码”。由于我将无法在库中使用 TestData 结构,因为它会因程序而异,因此处理此问题的唯一方法是使用接口。有没有更好的办法?


库配置


package config


import (

    "encoding/json"

    "fmt"

    "os"

)


// Base configuration struct

type Configuration struct {

    Filename string

    Data     interface{}

}


func (c *Configuration) Create(cData *Configuration) bool {

    cFile, err := os.Open(cData.Filename)

    defer cFile.Close()

    if err == nil {

        fmt.Println("Error(1) trying to create a configuration file. File '", cData.Filename, "' may already exist...")

        return false

    }

    cFile, err = os.Create(cData.Filename)

    if err != nil {

        fmt.Println("Error(2) trying to create a configuration file. File '", cData.Filename, "' may already exist...")

        return false

    }

    buffer, _ := json.MarshalIndent(cData.Data, "", "")

    cFile.Write(buffer)

    return true

}


func (c *Configuration) Read(cData *Configuration) bool {

    cFile, err := os.Open(cData.Filename)

    defer cFile.Close()

    if err != nil {

        fmt.Println("Error(1) trying to read a configuration file. File '", cData.Filename, "' may not already exist...")

        return false

    }

    jConfig := json.NewDecoder(cFile)

    jerr := jConfig.Decode(&cData.Data)

    if jerr != nil {

        panic(jerr)

    }

    return true

}

使用库配置的程序


package main


import (

    "fmt"


    "./config"

)


// struct basic para configuração

type TestData struct {

    URL  string

    Port string

}



MM们
浏览 168回答 2
2回答

HUX布斯

您试图断言它Config.Data是 type *TestData,但您将它分配给了TestData{"http", "8080"}上面。您可以使用复合文字的地址来创建指针:Config.Data = &TestData{"http", "8080"}如果您的配置已经存在,您的Read方法将Data使用默认的 json 数据类型填充该字段,可能是map[string]interface{}. 如果您将正确类型的指针分配给Datafirst,它将解码为预期的类型。Config.Data = &TestData{}Ans 因为Data是 an interface{},所以您不想使用指向该值的指针,因此&在编组和解组时不要使用该运算符。

大话西游666

您遇到错误的原因是因为您正在尝试解码为一种interface{}类型。在处理 JSON 对象时,它们map[string]interface{}默认由 encoding/json 包解码成类型。这会导致类型断言失败,因为 map[string]interface{} 的内存结构与结构的内存结构大不相同。更好的方法是使您的 TestData 结构体成为您的配置结构体的预期数据格式:// Base configuration structtype Configuration struct {    Filename string    Data     *TestData}然后在对文件数据进行解码时,该包会将数据解组到与其找到的数据最匹配的字段中。如果您需要对数据解组过程进行更多控制,您可以使用结构标记指定将哪些 JSON 字段解码为哪些结构成员。您可以在此处阅读有关 json 结构标记的更多信息:https : //golang.org/pkg/encoding/json/#Marshal
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go