9.2 两个比较有趣的 GO 知识点

优质
小牛编辑
125浏览
2023-12-01

为什么结构体作为map的值,不能通过map[key].成员属性 = "Xxx" 这种赋值

package main

import "fmt"

type Test struct {
    Name string

}
var list map[string]Test
func main() {

    list = make(map[string]Test)
    name := Test{"xiaoming"}
    list["name"] = name
    list["name"].Name = "Hello"  // 这一行编辑器会报错。  运行也会报错。
}

如上程序。为啥在list["name"].Name = "Hello" 这一行会报错。

修改: 更有趣的事情出现了

package main

import "fmt"

type Test struct {
    Name string
    Age  int
    People int
}
func (test Test) test() string {
    return test.Name
}

func (test Test) setName(name string) {
    test.Name = name
}

var list map[string]Test
func main() {

    list = make(map[string]Test)
    name := Test{"xiaoming",9, 15}
    list["name"] = name

    name.Name = "7889"
    list["name"] = name

    list["name"].setName("dsadsa")   // 但是这里通过方法却能修改name的值

    list["name"].Name = "Hello"   // 这里编译过不了。
}

我如果把Test的实例通过方法调用修改name的值,却可以修改。。。

回答

因为在Go里面所有的都是值copy,list["name"]取值的时候实际上是里面的struct的值完整的一个copy,如果允许了这样的操作list["name"].XXX这样的操作,那么实际上你修改的东西没有复制回原来的struct,所以你可以采用map[key]*struct的定义来进行操作,如下所示是可以正确操作的

package main

import (
    "fmt"
)

type A struct {
    Name string
}

func main() {
    m := map[string]*A{"a": &A{"hello"}}
    m["a"].Name = "Asta"
    fmt.Println(m)
}

有没有统一的方式解析post 表单传递的嵌套参数?

问题是这样的, 是post application/www-form-urlencoded 这样的表单提交,提交的参数一种是这样的

{"data"=>
  {"type"=>"notice",
   "title"=>"通知",
   "content"=>"<p>啦啦啦</p>",
 "user_id"=>1,
 }

另一种是这样

{"data"=>
  {"type"=>"notice",
   "title"=>"通知",
   "content"=>"<p>啦啦啦</p>",
   "option" => "true",
 "age"=>1,
}

以后可能有第三种,第四种

在经过 r.ParseForm()之后, re := r.PostForm; re值是:

map[user_id:[2] data[type]:[notice] data[title]:[通知] data[content]:[\u003cp\u003e啦啦啦\u003c/p\u003e]] 是一个map, 但是原来嵌套的data结构被平铺了。。。 变成了多个 data[xxx] 这样的key, 而处理之后想要返回的数据结构是 原来一样,不要data被平铺。 我知道可以定义嵌套的map,一一对应的赋值,但这样参数结构你就需要前后端都知道了,而且会很麻烦,其实逻辑只是把传来的参数原样json数据的返回, 请问有没有统一的方式序列化处理上面两种甚至多种嵌套的数据结构

回答

建议使用json方式来上传。