Q: golang指向map[string]interface{}的指针

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

Q: golang pointer to map[string]interface{}

问题

我(golang 新手)正在尝试在一个函数中创建一个 map[string]interface{}。代码可以编译和运行,但是 map 是空的。

package main

import (
	"fmt"
	"encoding/json"
)


func main() {
	var f interface{}
	var sJson string					// JSON string from VT
	var err error						// errors
	var b []byte						// bytearray of JSON string
	var rootMap map[string]interface{}
	
	rootMap = make(map[string]interface{})

	sJson=`{"key": "foo"}`
	
	fmt.Println(sJson)
	
	err = json2map(&b, &sJson, f, rootMap)
		
	if err != nil {	return }
	
	switch v := rootMap["key"].(type) {
		case float64:
			fmt.Printf("Value: %d",v)
		case string:
			fmt.Printf("Value: %s", v)
		case nil:
			fmt.Println("key is nil")			
		default:
			fmt.Println("type is unknown")			
	}		
}

func json2map(b *[]byte, sJson *string, f interface{}, myMap map[string]interface{}) error {
	var err error
	*b = []byte(*sJson)	
	err = json.Unmarshal(*b,&f)	
	myMap = f.(map[string]interface{})
	return err
}

输出结果为:

{"key": "foo"}
key is nil

我找到了这篇文章,其中描述了如何使用 map[string]string。这段代码按预期工作:

package main

import (
    "fmt"
)

type MyType struct {
    Value1 int
    Value2 string
}

func main() {
    myMap := make(map[string]string)
    myMap["key"] = "foo"
    ChangeMyMap(myMap)	
    fmt.Printf("Value : %s\n",  myMap["key"])    
}

func ChangeMyMap(TheMap map[string]string) {
    TheMap["key"] = "bar"
}

所以我认为我的问题与 map 的类型为 interface 而不是 string 有关,但我无法解释为什么第一个代码不起作用,而第二个代码起作用。

英文:

I (golang newbie) am trying to create a map[string]interfaces{} in a function. The code compiles and runs but the map is empty.

package main

import (
	"fmt"	
	"encoding/json"	
)


func main() {
	var f interface{}
	var sJson string					// JSON string from VT
	var err error						// errors
	var b []byte						// bytearray of JSON string
	var rootMap map[string]interface{}
	
	rootMap = make(map[string]interface{})

	sJson=`{"key": "foo"}`
	
	fmt.Println(sJson)
	
	err = json2map(&b, &sJson, f, rootMap)
		
	if err != nil {	return }
	
	switch v := rootMap["key"].(type) {
		case float64:
			fmt.Printf("Value: %d",v)
		case string:
			fmt.Printf("Value: %s", v)
		case nil:
			fmt.Println("key is nil")			
		default:
			fmt.Println("type is unknown")			
	}		
}

func json2map(b *[]byte, sJson *string, f interface{}, myMap map[string]interface{}) error {
	var err error
	*b = []byte(*sJson)	
	err = json.Unmarshal(*b,&f)	
	myMap = f.(map[string]interface{})
	return err
}

The output is:

{"key": "foo"}
key is nil

I found this article which describes how to use map[string]string. This code works as expected:

package main

import (
    "fmt"
)

type MyType struct {
    Value1 int
    Value2 string
}

func main() {
    myMap := make(map[string]string)
    myMap["key"] = "foo"
    ChangeMyMap(myMap)	
    fmt.Printf("Value : %s\n",  myMap["key"])    
}

func ChangeMyMap(TheMap map[string]string) {
    TheMap["key"] = "bar"
}

So I think my problem has to do with the map being of type interface instead of string but I cannot tell why the first code doesn't work, while the 2nd does.

答案1

得分: 5

这里有几个导致混淆的问题:

  • 你根本不需要 b。你正在传递一个指向字节切片的指针,在函数内部重新分配它。直接使用字符串即可。
  • 没有必要使用指向 sJson 字符串的指针。字符串是不可变的,并且你并没有尝试重新分配 sJson 变量。
  • 你正在将空接口解组为 myMap 的内容,然后尝试重新分配 myMap 变量的内容为 f 的内容。由于 myMap 不是指针,该赋值只在函数内部有效。直接解组为 myMap

如果你更改这些内容,你会发现 json2map 函数最终只有一行,并且可以完全删除:

func json2map(sJson string, myMap map[string]interface{}) error {
    return json.Unmarshal([]byte(sJson), &myMap)
}
英文:

There's a number of things causing confusion here:

  • You don't need b at all. You're passing a pointer to a byte slice that you're reassigning inside the function. Just use the string directly.
  • There's no need to us a pointer to the sJson string. Strings are immutable, and you're not trying to reassign the sJson variable.
  • You're unmarshaling into an empty interface, and then trying to reassign the myMap variable to the contents of f. Since myMap isn't a pointer, that assignment is only scoped to within the function. Just unmarshal directly into myMap

If you change those things, you'll find the json2map function ends up being one line, and can be dropped altogether:

func json2map(sJson string, myMap map[string]interface{}) error {
	return json.Unmarshal([]byte(sJson), &myMap)
}

huangapple
  • 本文由 发表于 2015年11月24日 21:55:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/33895505.html
匿名

发表评论

匿名网友

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

确定