在此上下文中,"make"函数对地图执行什么作用



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

这是我用来测试make函数在做什么的小例子。我有点通过修补弄清楚了它,但我不明白它实际上在做什么,以及为什么它是必要的。

type ErrorHandler struct {
    Errors map[string]string
}
type Form struct {
    ErrorHandler
}
func main() {
    form := &Form{}
    if true {
        fmt.Printf("%pn", &form.Errors)
    } else {
        form.Errors = make(map[string]string)
        fmt.Printf("%pn", &form.Errors)
    }
}

在上面的示例中,我尝试将 if 语句从 true 更改为 false,以查看内存地址是否根据是否使用 make 函数而更改,并且两种情况都保持不变。我在这里阅读了答案,他说它的用途之一是"创建预先分配空间的地图"——老实说,这对我来说意义不大,因为我是指针和所有这些的新手,但"创建地图"部分让我认为这就像在 ErrorHandler 结构中重新初始化该错误映射, 这会将其分配给新的内存地址,是吗?但是不,它们保持不变。

所以我尝试在映射中创建一个值,一次没有 make 函数,一次使用 make 函数if条件给了我一个错误,说assignment to entry in nil mapgoroutine [running]else语句打印"哈哈",这就是我设置的:

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]string设置为 nil,因为当我打印出来时,我看到的是"map[]"而不是"nil"......这令人困惑。

有人可以解释一下吗?这里如何使用这种goroutine?也许这就是我正在寻找的答案。以前从未使用过。

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

例如,在我的错误处理程序结构中,我有一个看起来像这样的方法:

func (this *ErrorHandler) HandleErr(err string) {
    this.Errors = make(map[string]string)
    this.Errors["Error"] = err
}

在我的表单结构中,我还有另一种验证表单的方法,但也使用"this.错误 = 方法顶部的 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 时,地址不会更改。错误

至于推送到您没有make的地图时的 nil 错误......

非女仆地图还没有"数据"段,因此您会收到零指针错误。

与做不同:

var i *int
*i = 5

还会导致零错误

希望这一切都是有道理的,并有助于揭示混乱。

首先,回答你的问题:

与 https://golang.org/pkg/builtin/#make 相比

make内置函数分配和初始化切片,映射或chan类型的对象(仅)[...]

地图:根据大小进行初始分配,但生成的映射的长度为 0。可以省略大小,在这种情况下分配了较小的起始大小。

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

第三,make 初始化地图,你可能不应该在每次HandleErr调用中都使用它,因为它会替换你当前的地图。我认为您想要的可能是像NewErrorHandlerNewForm这样的初始化功能。它有点适合您的结构。例如:

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{}}
}

最新更新