Struct 什么是;制造;函数在该上下文中对映射执行什么操作

Struct 什么是;制造;函数在该上下文中对映射执行什么操作,struct,go,Struct,Go,我是新手,几天前正在寻找一个关于表单的教程,现在我已经对自己有了更多的了解,我正试图创建自己的错误处理程序,可以用于我的所有结构,有点像一个抽象类,但是我从教程中看到的示例让我有点困惑 下面是一个小例子,我用它来测试make函数在做什么。我通过修修补补找到了答案,但我不明白它到底在做什么,为什么有必要这么做 type ErrorHandler struct { Errors map[string]string } type Form struct { ErrorHandler

我是新手,几天前正在寻找一个关于表单的教程,现在我已经对自己有了更多的了解,我正试图创建自己的错误处理程序,可以用于我的所有结构,有点像一个抽象类,但是我从教程中看到的示例让我有点困惑

下面是一个小例子,我用它来测试
make
函数在做什么。我通过修修补补找到了答案,但我不明白它到底在做什么,为什么有必要这么做

type ErrorHandler struct {
    Errors map[string]string
}

type Form struct {
    ErrorHandler
}

func main() {
    form := &Form{}

    if true {
        fmt.Printf("%p\n", &form.Errors)
    } else {
        form.Errors = make(map[string]string)
        fmt.Printf("%p\n", &form.Errors)
    }
}
在上面的示例中,我尝试将if语句从true更改为false,以查看内存地址是否根据是否使用
make
函数而改变,并且在这两种情况下保持不变。我读了答案,他说它的一个用途是“创建一个预先分配了空间的映射”——这对我来说真的没有什么意义,因为我对指针和所有这些都不熟悉,但“创建映射”部分让我觉得这就像在ErrorHandler结构中重新初始化错误映射,这会将它分配给一个新的内存地址,是吗?但不,它们保持不变

所以我尝试在地图中创建一个值,一次不使用make函数,一次使用make函数。
if
条件给了我一个错误,说
赋值给nil map中的条目
goroutine[running]
,而
else
语句打印“haha”,这就是我设置的:

type ErrorHandler struct {
    Errors map[string]string
}

type Form struct {
    ErrorHandler
}

func main() {
    form := &Form{}

    if true {
        form.Errors["blah"] = "haha"
        fmt.Printf(form.Errors["blah"])
    } else {
        form.Errors = make(map[string]string)
        form.Errors["blah"] = "haha"
        fmt.Printf(form.Errors["blah"])
    }
}
所以我有点明白make函数在做什么,但不完全清楚。就我所知,如果我要将项目“推”到地图中,我需要使用
make
功能,但我不明白为什么有必要这样做。为什么在我的结构中将
map[string]字符串设置为nil,因为当我打印出来时,我看到的是“map[]”,而不是“nil”。。。那太令人困惑了

有人能解释一下吗?这个
goroutine
在这里是如何使用的?也许这就是我想要的答案。。以前从没用过

另外,由于我必须使用
make
,有没有一种方法可以让它自动发生,而不必把它放在每个方法的顶部

例如,在我的ErrorHandler结构中,我有一个如下所示的方法:

func (this *ErrorHandler) HandleErr(err string) {
    this.Errors = make(map[string]string)
    this.Errors["Error"] = err
}
在我的表单结构中,我还有另一个验证表单的方法,但也使用了方法顶部的`this.Errors=make(map[string]string)。。。我觉得不干


非常感谢您的帮助。

请将地图视为一个结构,其中包含指向下划线地图结构的指针和大小(可能还有其他内容,不确定)

例如,可以这样想:

struct Map {
  data *Entries
  size int
}
make,根据传递给make的大小(如果有)分配条目的初始值

当你说:

form.Errors = make(map[string]string)
就像说:

form.Errors = struct { data : malloc(sizeof(Entries)*capacity), size : 0 }
将“数据”和“大小”变量复制到表单中。错误

实际字段“form.Errors”在内存中仍然是相同的位置,form.Errors的内部值已更改以匹配make返回的值

因此,当您查看&form.Errors时,地址不会更改

至于推到地图时出现的零错误,您没有
make

un-maid映射还没有“数据”段,因此会出现零指针错误

就像做:

var i *int
*i = 5
也会导致零错误


希望所有这些都是有意义的,并有助于澄清混淆。

将贴图视为一个结构,其中包含指向下划线贴图结构的指针和大小(可能还有其他内容,不确定)

例如,可以这样想:

struct Map {
  data *Entries
  size int
}
make,根据传递给make的大小(如果有)分配条目的初始值

当你说:

form.Errors = make(map[string]string)
就像说:

form.Errors = struct { data : malloc(sizeof(Entries)*capacity), size : 0 }
将“数据”和“大小”变量复制到表单中。错误

实际字段“form.Errors”在内存中仍然是相同的位置,form.Errors的内部值已更改以匹配make返回的值

因此,当您查看&form.Errors时,地址不会更改

至于推到地图时出现的零错误,您没有
make

un-maid映射还没有“数据”段,因此会出现零指针错误

就像做:

var i *int
*i = 5
也会导致零错误


希望所有这些都是有意义的,并有助于澄清困惑。

首先,回答您的问题:

make内置函数分配和初始化类型为slice、map或chan的对象(仅限)[…]

地图:根据大小进行初始分配,但 结果贴图的长度为0。在这种情况下,可以省略尺寸 分配一个小的起始大小

其次,您发布的代码中没有goroutine

第三,make初始化映射,您可能不应该在每次
HandleErr
调用中使用它,因为它将替换当前映射。我认为您需要的可能是一个初始化函数,如
NewErrorHandler
NewForm
。它有点适合你的结构。例如:

func NewErrorHandler() ErrorHandler {
    return ErrorHandler{make(map[string]string)}
}
最后,为什么映射不能自动初始化?若有,你们将无法控制地图的初始大小。如果您有任务关键型代码,并且希望它具有快速或低内存,并且知道其大小,那么这可能很重要

还有另外一种初始化地图的方法。如果要初始化空映射,可以编写:
map[string]string{}
。如果要创建具有初始值的贴图,请执行以下操作:

map[string]string{
    "a": "b",
    "c": "d",
}
因此,您可以编写NewErrorHandler函数,如下所示:

func NewErrorHandler() ErrorHandler {
    return ErrorHandler{map[string]string{}}
}

首先,回答你的问题:

make内置函数分配和初始化类型为slice、map或chan的对象(仅限)[…]

地图:根据大小进行初始分配,但 结果贴图的长度为0。在这种情况下,可以省略尺寸 分配一个小的起始大小

其次,您发布的代码中没有goroutine

第三,使初始化