我正在解析大量 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 行时,我往往会觉得“哇哦?这里做错了什么,妈妈?”
Go 中有任何类型的单行代码吗?
谢谢
最佳答案
正如 Uvelichitel 所指出的,您可以使用类型化的字符串:
type IP string
var hits = make(map[IP]uint)
hits[IP("127.0.0.1")]++
或者您可以使用现有的标准库 IP 类型:
var hits = make(map[net.IP]uint)
hits[net.ParseIP("127.0.0.1")]++
两者都可以清楚地表明您指的是 IP,而不会因每次增量循环结构片而引入开销。后者的优点是为您提供对您需要执行的任何其他 IP 操作的完整 stdlib 支持,以及更紧凑的表示形式(IPv4 地址为 4 个字节,而不是 7-15 个字符的 UTF-8 字符串),但代价是解析琴弦。哪一个更好取决于您的具体用例。
关于戈朗 : optimal way of typing associative slices?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44069593/