Dictionary golang创建多级字符串映射
我是一个非常新的语言。我正在努力解决以下用例 我想将会话id(字符串)和请求编号(字符串)存储在映射中以进行重复检查。当地图中没有条目时,它应该创建一个条目,否则它应该返回一个标志,表明该条目已经存在Dictionary golang创建多级字符串映射,dictionary,go,Dictionary,Go,我是一个非常新的语言。我正在努力解决以下用例 我想将会话id(字符串)和请求编号(字符串)存储在映射中以进行重复检查。当地图中没有条目时,它应该创建一个条目,否则它应该返回一个标志,表明该条目已经存在 package main import "fmt" func main() { mySessionData := make(map[string]map[string]bool) var ret bool ret = chkDuplicate(mySessionDat
package main
import "fmt"
func main() {
mySessionData := make(map[string]map[string]bool)
var ret bool
ret = chkDuplicate(mySessionData, "session1", "1")
fmt.Println(mySessionData)
ret = chkDuplicate(mySessionData, "session1", "2")
fmt.Println(mySessionData)
ret = chkDuplicate(mySessionData, "session1", "3")
fmt.Println(mySessionData)
ret = chkDuplicate(mySessionData, "session1", "2")
fmt.Println(mySessionData)
ret = chkDuplicate(mySessionData, "session1", "4")
fmt.Println(mySessionData)
fmt.Println(ret)
delete(mySessionData, "session1")
fmt.Println(mySessionData)
}
func chkDuplicate(m map[string]map[string]bool, sess string, Reqno string) bool {
var found bool
val, found := m[sess][Reqno]
if !found {
fmt.Println(val)
valu := make(map[string]bool)
valu[Reqno] = true
m[sess] = valu
return !found
}
return !found
}
我面临的问题是,每次调用函数时,值都被过度写入。
我做错了什么?sess变量始终等于session1,所以您只需重写键session1的值。你必须有难以辨别的钥匙 如果要检查重复项,请执行以下操作:
package main
import "fmt"
func main() {
mySessionData := make(map[string]bool)
chkDuplicate(mySessionData, "session1", "1")
chkDuplicate(mySessionData, "session1", "1")
chkDuplicate(mySessionData, "session2", "1")
fmt.Println(mySessionData) # two keys printed
}
func chkDuplicate(m map[string]bool, sess string, Reqno string) bool {
key := fmt.Sprintf("%s-%s", sess, Reqno)
_, found := m[key]
if !found {
m[key] = true
}
return !found
}
sess变量始终等于session1,所以您只需覆盖键session1的值。你必须有难以辨别的钥匙 如果要检查重复项,请执行以下操作:
package main
import "fmt"
func main() {
mySessionData := make(map[string]bool)
chkDuplicate(mySessionData, "session1", "1")
chkDuplicate(mySessionData, "session1", "1")
chkDuplicate(mySessionData, "session2", "1")
fmt.Println(mySessionData) # two keys printed
}
func chkDuplicate(m map[string]bool, sess string, Reqno string) bool {
key := fmt.Sprintf("%s-%s", sess, Reqno)
_, found := m[key]
if !found {
m[key] = true
}
return !found
}
如果给定会话ID的映射尚不存在(如果给定请求号不在其中,则不存在),则只需创建内部映射(会话映射)的值,否则从中清除以前存储的任何请求号 由于您使用
bool
作为内部映射(会话映射)的值类型,因此可以利用此功能编写更简单的代码(使用不在映射中的键对映射进行索引将生成值类型的零值,对于bool
类型,此值为false
,正确地告知键不在映射中):
测试它:
func main() {
mySessionData := make(map[string]map[string]bool)
for _, reqNo := range []string{"1", "2", "3", "2", "4"} {
ret := chkDuplicate(mySessionData, "session1", reqNo)
fmt.Println(ret, mySessionData)
}
delete(mySessionData, "session1")
fmt.Println(mySessionData)
}
输出(在上尝试):
请注意,bool
——虽然可能很小,但确实需要内存。因为我们可以查询键是否在映射中,所以我们可以选择使用不需要内存的值类型,例如空结构(struct{}
)。因此,它可能看起来像这样:
func chkDuplicate(m map[string]map[string]struct{}, sess string, Reqno string) bool {
sessMap := m[sess]
if sessMap == nil {
m[sess] = map[string]struct{}{Reqno: struct{}{}}
return false
}
if _, ok := sessMap[Reqno]; ok {
return true
}
sessMap[Reqno] = struct{}{}
return false
}
测试和结果(几乎)是一样的,请在桌面上试用
警告一句:从这个例子来看,您似乎希望使用它来跟踪以前是否提供过(web)请求,其中通常涉及多个goroutine。此解决方案对于并发使用不安全如果给定会话ID的映射尚不存在(并且如果给定的请求号不在其中,则不存在),则只需创建内部映射(会话映射)的值,否则从中清除以前存储的任何请求号 由于您使用
bool
作为内部映射(会话映射)的值类型,因此可以利用此功能编写更简单的代码(使用不在映射中的键对映射进行索引将生成值类型的零值,对于bool
类型,此值为false
,正确地告知键不在映射中):
测试它:
func main() {
mySessionData := make(map[string]map[string]bool)
for _, reqNo := range []string{"1", "2", "3", "2", "4"} {
ret := chkDuplicate(mySessionData, "session1", reqNo)
fmt.Println(ret, mySessionData)
}
delete(mySessionData, "session1")
fmt.Println(mySessionData)
}
输出(在上尝试):
请注意,bool
——虽然可能很小,但确实需要内存。因为我们可以查询键是否在映射中,所以我们可以选择使用不需要内存的值类型,例如空结构(struct{}
)。因此,它可能看起来像这样:
func chkDuplicate(m map[string]map[string]struct{}, sess string, Reqno string) bool {
sessMap := m[sess]
if sessMap == nil {
m[sess] = map[string]struct{}{Reqno: struct{}{}}
return false
}
if _, ok := sessMap[Reqno]; ok {
return true
}
sessMap[Reqno] = struct{}{}
return false
}
测试和结果(几乎)是一样的,请在桌面上试用
警告一句:从这个例子来看,您似乎希望使用它来跟踪以前是否提供过(web)请求,其中通常涉及多个goroutine。此解决方案对于并发使用不安全使用结构键而不是多级映射通常更简单:
使用结构键而不是多级映射通常更简单:
每次发现为false时,您都要创建一个新映射,不要这样做,检查m[sess]是否为nil,然后才创建它,如果不是nil,只需将m[sess][Reqno]设置为true即可。您没有在任何地方使用
val
变量,因为每次检查重复项时,您都会为req
创建一个新映射。每次发现错误时,您都会创建一个新映射,不要这样做,请检查m[sess]是否为nil,然后才创建它,如果不是nil,请将m[sess][Reqno]设置为true。您没有在任何地方使用val
变量,因为每次检查重复项时,您都要为req
创建一个新映射。我正在寻找类似于Perl散列的东西。因此,当我访问mySessionData[“session1”][“2”]时,变量mySessionData应该能够返回值true,但当我说mySessionData[“session1”][“6”]时,则返回nil。我正在寻找类似于散列的Perl散列的东西。因此,当我访问mySessionData[“session1”][“2”]时,变量mySessionData应该能够返回值true,但当说mySessionData[“session1”][“6”]时,应该返回值nil