Golang:键入关联切片的最佳方式?

时间:2017-05-19 12:01:34

标签: go

我正在解析大量追踪目标的HTTP日志,告诉每个IP地址生成了多少请求。

我做的第一件事就是:

var hits = make(map[string]uint)

// so I could populate it with
hits[ipAddr]++

但是,我想让它“打字”,以便立即明确hits[string]uint使用IP地址作为字符串标识符。我想,也许一个结构可以帮助我:

type Hit struct {
    IP    string
    Count uint
}

但是那种方式(我认为)我正在失去性能,因为现在我如何真正寻找特定的命中来增加它的数量。我容忍我在这里可能是偏执狂,并且可以简单地进行循环:

var hits = make([]Hit)

// TrackHit just damn tracks it
func TrackHit(ip string) {
    for hit, _ := range hits {
        if hit.IP == ip {
             hit.Count++
             return
        }
    }

    append(hits, Hit{
        IP:    ip,
        Count: 0,
    })
}

但这看起来......不是最理想的。我认为所有可以写成1行的东西都会让你变得专业,当1行变成13行时,我倾向于觉得“whaaa?在这里做错了什么,妈妈?”

Go中的任何类型的单行?

由于

1 个答案:

答案 0 :(得分:4)

正如Uvelichitel指出的那样,你可以使用一个打字的字符串:

type IP string
var hits = make(map[IP]uint)
hits[IP("127.0.0.1")]++

或者您可以使用现有的stdlib IP类型:

var hits = make(map[net.IP]uint)
hits[net.ParseIP("127.0.0.1")]++

要么明确表示你是指IP,而不是通过循环遍历每个增量的一个结构片段来引入开销。后者的优点是可以为您需要执行的任何其他IP操作提供完整的stdlib支持,以及更加紧凑的表示(IPv4地址为4个字节而不是7-15个字符的UTF-8字符串),代价是解析字符串。哪一个更好将取决于您的具体用例。