戈朗 : optimal way of typing associative slices?

标签 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 行时,我往往会觉得“哇哦?这里做错了什么,妈妈?”

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/

相关文章:

go - 使用 Go 在项目级别安装包

image - 在刚刚创建的 Go 中提供图像

multithreading - 我可以一次对所有 slice 项目执行操作吗?

go - golang 中 uint8 的读写是原子的吗?

go - Go 中的映射不是线程安全的意味着什么?

go - Golang 中类似于定时器的闹钟功能

github - Docker:从私有(private) GitHub 存储库中获取

go - 加扰/解扰整数值到/从十六进制字符串

html - 如何将变量及其值发送到html

session - Gorilla session 文件系统存储找不到 session 文件