保存和加载自定义类型

huangapple go评论109阅读模式
英文:

save and loading custom types

问题

我有一个自定义类型 map[string]map[string]string,尝试将其保存在Google Datastore中,保存操作正常工作。然而,加载函数报错 assignment to entry in nil map

// Address 表示地址
type Address map[string]map[string]string

上面的类型是一个 mapmap[string]string,用于保存不同类型的地址。

// Load 函数从 PropertyLoaderInterface 帮助 Datastore 加载该对象
func (a *Address) Load(dp []datastore.Property) error {
    for _, property := range dp {
        (*a)[property.Name] = util.InterfaceToMapString(property.Value)
    }
    return nil
}

在加载函数中,我对 Address 进行了解引用,它是一个 mapmap[string]string,它保存了以下示例 JSON 格式的数据。

"Company":{
    "physicalAddress": "",
    "postalAddress": "",
    "physicalCity": "",
    "postalCity": "",
    "physicalCode": "",
    "postalCode": "",
    "physicalCountry": "",
    "postalCountry": ""
}

下面的保存函数工作正常,并且数据被存储在 Datastore 中。然而,加载函数却有一个棘手的 bug。

// Save 函数从 PropertyLoaderInterface 帮助 Datastore 保存该对象
func (a *Address) Save() ([]datastore.Property, error) {
    properties := []datastore.Property{}
    for name, value := range *a {
        properties = append(properties, datastore.Property{
            Name:    name,
            NoIndex: true,
            Value:   util.MapToJSONString(value),
        })
    }

    return properties, nil
}

Address 结构的工作加载函数

func (a *Address) Load(dp []datastore.Property) error {
    *a = make(Address)

    for _, property := range dp {
        (*a)[property.Name] = util.InterfaceToMapString(property.Value)
    }
    return nil
}
英文:

I have a custom type map[string]map[string]string am trying to save in Google Datastore, the save works as expected. However the load functions complains about assignment to entry in nil map

//Address represents address
type Address map[string]map[string]string

Type above is a map of map[string]string, target at saving different address types.

//Load function from PropertyLoaderInterface helps datastore load this object
func (a *Address) Load(dp []datastore.Property) error {
	for _, property := range dp {
		(*a)[property.Name] = util.InterfaceToMapString(property.Value)
	}
	return nil
}

In the load function I deference the Address which is a map of map[string]string, it saves the following example JSON format.

"Company":{
    "physicalAddress": "",
    "postalAddress": "",
    "physicalCity": "",
    "postalCity": "",
    "physicalCode": "",
    "postalCode": "",
    "physicalCountry": "",
    "postalCountry": ""
}

Save function below works well and data is store in datastore. The Load is however rather a tricky bugger.

//Save function from PropertyLoaderInterface helps datastore save this object
func (a *Address) Save() ([]datastore.Property, error) {
	propertise := []datastore.Property{}
	for name, value := range *a {
		propertise = append(propertise, datastore.Property{Name: name,
			NoIndex: true,
			Value:   util.MapToJSONString(value)})
	}

	return propertise, nil
}

Working load for Address struct

func (a *Address) Load(dp []datastore.Property) error {
    *a = make(Address)

    for _, property := range dp {
        (*a)[property.Name] = util.InterfaceToMapString(property.Value)
    }
    return nil
}

答案1

得分: 2

首先,关于声明 - https://stackoverflow.com/a/42901715/4720042

接下来,我认为你应该使用自定义结构体来实现这个目的。
即使你仍然想使用map[string]map[string]string,你也不能给一个在映射中没有明确定义的字段赋值,比如property.Name

如果你计划在以后添加元素,你必须使用make来初始化该映射。

英文:

First, regarding the declarations - https://stackoverflow.com/a/42901715/4720042

Next, I feel you should instead use a custom struct for this purpose.
Even if you still want to use a map[string]map[string]string, you cannot assign to a field in a map that hasn't been explicitly defined viz. property.Name

You have to initialize that map with make if you plan on adding the elements later.

huangapple
  • 本文由 发表于 2017年4月9日 20:24:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/43306655.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定