我正在阅读 Go 的compress/flate包,我发现了这段奇怪的代码 [1]:n := int32(len(list))list = list[0 : n+1]list[n] = maxNode()在上下文中,list保证指向一个后面有更多数据的数组。这是一个私有函数,因此不能在库外滥用。对我来说,这似乎是一个可怕的黑客,应该是一个运行时异常。例如,以下 D 代码会生成 RangeError:auto x = [1, 2, 3];auto y = x[0 .. 2];y = y[0 .. 3];使用以下方法可以更简单地(并且看起来更安全)滥用切片:x := []int{1, 2, 3}y = x[:2]y = append(y, 4) // x is now [1, 2, 4] because of how append works但是这两种解决方案似乎都非常老套和可怕,恕我直言,不应该像他们那样工作。这种东西被认为是惯用的 Go 代码吗?如果是,以上哪一个更符合地道?[1] - http://golang.org/src/pkg/compress/flate/huffman_code.go#L136
2 回答
Cats萌萌
TA贡献1805条经验 获得超9个赞
这不是滥用切片,这只是完美地使用了切片:数组上的窗口。
我将从我所做的另一个相关答案中获取此插图:
array : [0 0 0 0 0 0 0 0 0 0 0 0]
array : <---- capacity --->
slice : [0 0 0 0]
slice : <---- capacity --->
当数组大于切片时,当您知道不会离开底层数组时,通过扩展一个更大的切片来获取更大的切片是正常和标准的(可以使用 验证cap())。
关于您举的错误代码,是的,这可能很危险,但是数组和切片是语言的最基本结构之一,如果您想避免此类错误,则必须在使用它们之前了解它们。我个人认为任何 Go 编码员不仅应该知道 API,还应该知道slice是什么。
在您链接到的代码中,简短的分析表明,不可能像list创建的那样溢出
list := make([]literalNode, len(freq)+1)
并且后来调整为count不能大于len(freq):
list = list[0:count]
人们可能更喜欢多一些注释,但由于包含的函数list = list[0 : n+1]是私有的并且仅从一个地方调用,因此也可以认为注释冗长和代码晦涩之间的平衡听起来是正确的。有太多的注释隐藏了代码是很痛苦的,任何需要阅读这段代码的人都可以像我一样轻松地检查是否有溢出。
- 2 回答
- 0 关注
- 183 浏览
添加回答
举报
0/150
提交
取消