Golang:多维字符串数组而不是地图

时间:2016-07-25 14:17:40

标签: arrays string dictionary go

在我的项目中,我需要读取一个值作为全局变量,所以我使用的是map(全局变量)

var url = make(map[string]string)

我偶尔会遇到错误"Concurrent writes",因为我在一个函数中赋值(cant赋值为global,因为它给出了一个错误的非声明性语句)。

url["test"] = "http://google.com"

在PHP中,我可以通过multidimensioanl数组轻松完成此操作并读取值。有没有办法我可以在Go中使用多维数组或地图来分配和读取函数?

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

当Go运行时检测到不同goroutine对映射的并发写入时,会发生Concurrent writes错误。这是go1.6中添加的一项功能:

https://blog.golang.org/go1.6

  

运行时添加了轻量级,尽力而为的并发滥用映射的方法。和往常一样,如果一个goroutine正在写一张地图,那么其他任何goroutine都不应该同时读取或写入地图。如果运行时检测到此情况,则会打印诊断并使程序崩溃。了解问题的最佳方法是在竞赛检测器下运行它,这将更可靠地识别比赛并提供更多细节。

可以在全局级别初始化地图 - 有关示例,请参阅https://play.golang.org/p/AjqtQBGMEM(或以下)。相同的代码片段显示了如何使用同步机制阻止地图数据争用 - 在写入地图之前使用互斥锁,锁定,然后解锁。

package main

import (
    "fmt"
    "sync"
)

var mu sync.Mutex
var mymap = map[string]string{"hello": "world", "foo": "bar"}

func main() {
    demo()
}

func demo() {
    mu.Lock()
    defer mu.Unlock()
    mymap["hello"] = "gophers"
    fmt.Println("hello, ", mymap["hello"])  
}

避免数据竞争的另一种方法是使用大小为1(非缓冲)的通道,类似于https://tour.golang.org/concurrency/2中的Tour示例:从通道中提取地图,写入并放置它回到频道。

https://golang.org/doc/articles/race_detector.html提供了有关数据竞争和Go竞争检测器的更多信息 - 这是一种非常有用的工具,用于识别并发访问中难以跟踪的错误。