Go语言中无法正确访问map[string]*自定义结构体的问题咨询
问题本质
Go语言中map的value如果是值类型(非指针)时是不可寻址的,无法直接修改value结构体的内部字段;如果使用指针类型作为value,仅初始化map本身不会自动为每个key对应的结构体分配内存,未初始化就访问会触发空指针异常(NRE)。
实现方案
方案1:保留map[string]ZipStructure值类型定义
如果不想修改原结构体定义,通过先取出值修改再回写,或者直接赋值完整结构体的方式操作:
// 第一步:初始化map var config ServerConfig config.ClusterSetupZip = make(map[string]ZipStructure) // 操作方式1:直接赋值完整结构体(推荐) config.ClusterSetupZip[DirName] = ZipStructure{ Pfx: bytes, Cert: certBytes, Key: keyBytes, Json: jsonBytes, } // 操作方式2:修改已有项的字段 // 先取出值拷贝 zs := config.ClusterSetupZip[DirName] // 修改拷贝的字段 zs.Pfx = bytes // 回写覆盖map中原有值 config.ClusterSetupZip[DirName] = zs
方案2:使用map[string]*ZipStructure指针类型定义
使用指针类型可以直接修改结构体字段,但需要额外为每个key初始化对应的结构体实例,避免空指针:
// 修改ServerConfig定义 type ServerConfig struct { ClusterSetupZip map[string]*ZipStructure } // 第一步:初始化map var config ServerConfig config.ClusterSetupZip = make(map[string]*ZipStructure, 4) // 这里的4是容量预分配,不会初始化实际元素 // 第二步:为指定key初始化结构体实例(缺少这步会触发NRE) if _, ok := config.ClusterSetupZip[DirName]; !ok { config.ClusterSetupZip[DirName] = &ZipStructure{} // 为结构体分配实际内存 } // 现在可以直接修改结构体字段 config.ClusterSetupZip[DirName].Pfx = bytes
常见错误说明
之前使用指针类型map触发NRE的原因是:make仅初始化了map的底层数据结构,map中所有键对应的指针默认是nil,直接访问nil指针的字段就会触发空指针引用错误。
内容的提问来源于stack exchange,提问作者OmerMichleviz
相关产品推荐
相关产品推荐

