douque9815 2013-07-06 06:18
浏览 57
已采纳

工作是否超出了切片的习惯用法?

I was reading through Go's compress/flate package, and I found this odd piece of code [1]:

n := int32(len(list))
list = list[0 : n+1]
list[n] = maxNode()

In context, list is guaranteed to be pointing to an array with more data after. This is a private function, so it can't be misused outside the library.

To me, this seems like a scary hack that should be a runtime exception. For example, the following D code generates a RangeError:

auto x = [1, 2, 3];
auto y = x[0 .. 2];
y = y[0 .. 3];

Abusing slices could be done more simply (and also look more safe) with the following:

x := []int{1, 2, 3}
y = x[:2]
y = append(y, 4) // x is now [1, 2, 4] because of how append works

But both solutions seem very hacky and scary and, IMHO, should not work as they do. Is this sort of thing considered idiomatic Go code? If so, which of the the above is more idiomatic?

[1] - http://golang.org/src/pkg/compress/flate/huffman_code.go#L136

  • 写回答

2条回答 默认 最新

  • dpgbh20688 2013-07-06 06:21
    关注

    This is not abusing the slice, this is just perfectly using what a slice is : a window over an array.

    I'll take this illustration from another related answer I made :

     array : [0 0 0 0 0 0 0 0 0 0 0 0]
     array :  <----   capacity   --->
     slice :     [0 0 0 0]
     slice :      <---- capacity ---> 
    

    When the array is greater than the slice it's normal and standard to take a greater slice by extending one when you know you don't go out of the underlying array (which can be verified using cap()).

    Regarding your buggy code you give as example, yes, it might be dangerous, but arrays and slices are among the most basic structures of the languages and you must understand them before you use them if you want to avoid such bugs. I personally think that any go coder should not only know the API but also what are slices.


    In the code you link to, a short analysis shows that there is no possible overflow possible as list is created as

    list := make([]literalNode, len(freq)+1)
    

    and is later resized to count which can't be greater than len(freq) :

    list = list[0:count]
    

    One might have preferred a few more comments but as the function containing list = list[0 : n+1] is private and called from only one place, it might also be considered the balancing between comment verbosity and code obscurity sounds right. It's painful to have too much comments hiding the code and anybody in need to read this code is able to easily check there is no overflow just like I did.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 高德地图点聚合中Marker的位置无法实时更新
  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办