将接口传递给函数

时间:2018-08-17 02:20:26

标签: json go

我正在尝试编写一个采用json文件名和配置结构的配置包。它应该将json解组到传入的结构中并返回它。 我正在尝试使用界面,以便可以传递我想要的任何结构

错误是:

panic: interface conversion: interface {} is map[string]interface {}, not *main.ConfigurationData

我不太确定如何解决此问题。

这是我的主要包裹

package main

import (
    "config"
    "commons"
)

type ConfigurationData struct {
    S3ARN string `json:"S3ARN"`
    SQSQueueUrl string `json:"SQSQueueUrl"`
}

var configData *ConfigurationData

func main(){
    configData=config.Load("aws.config.json",configData).(*ConfigurationData)
    commons.Dump(configData)
}

这是我的配置包

package config

import (
    "os"
    "encoding/json"
    "sync"
    "commons"
)

var configLock = new(sync.RWMutex)

func Load(filename string,config interface{})interface{} {
    file, err := os.Open(filename)
    commons.CheckErrorf(err, "Config Open Error")
    defer file.Close()
    decoder := json.NewDecoder(file)
    configLock.Lock()
    err = decoder.Decode(&config)
    commons.CheckErrorf(err, "Config Decode Error")
    configLock.Unlock()
    return config
}

2 个答案:

答案 0 :(得分:1)

answer很好地解释了为什么您会收到异常。

您应该做什么:

encoding / json 包遇到实现 Marshaler 接口的类型时,它将使用该类型的MarshalJSON()方法而不是默认的封送处理代码来将对象转换为JSON。同样,在解码JSON对象时,它会测试该对象是否实现了 Unmarshaler 接口,如果是,它将使用UnmarshalJSON()方法而不是默认的非编组行为。

为此,我的解决方案是在*ConfigurationData上实现 UnmarshalJSON 方法,并且方法Load应该接受Unmarshaler接口,而不是interface{}。 / p>

您可以在此处了解有关技术的更多信息:https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/

然后,您可以简单地在json.Unmarshal(b, &config)方法中执行Load,其中 b 是从文件中[]byte读取的。

答案 1 :(得分:0)

根据documentation on json.Unmarshall解组为接口值将解组为预定义类型之一的新结构:

  

要将JSON解组为接口值,Unmarshal存储以下内容之一:   这些在界面值中:

bool, for JSON booleans 
float64, for JSON numbers
string, for JSON
strings []interface{}, for JSON arrays 
map[string]interface{}, for JSON objects
nil for JSON null

在您的情况下,选择的类型为map[string]interface{}。在您的函数中,指向该新未编组结构的指针存储在config参数中并返回。之所以会出现恐慌,是因为返回的值的类型不是您所断言的类型。