【问题标题】:How to inspect slice header?如何检查切片头?
【发布时间】:2019-01-15 09:19:07
【问题描述】:

这是来自slices的略微修改的代码

var buffer [256] byte

func SubtractOneFromLength(slice []byte) []byte {
    slice = slice[0 : len(slice)-1]
    return slice
}

func main() {
    slice := buffer[10:20]
    fmt.Println("Before: len(slice) =", len(slice))
    newSlice := SubtractOneFromLength(slice)
    fmt.Println("After:  len(slice) =", len(slice))
    fmt.Println("After:  len(newSlice) =", len(newSlice))
    newSlice2 := SubtractOneFromLength(newSlice)
    fmt.Println("After:  len(newSlice2) =", len(newSlice2))
}

它说切片参数的内容可以被函数修改,但它的标题不能。 如何在我的屏幕上打印 newSlice2 的标题?

【问题讨论】:

    标签: go slice


    【解决方案1】:

    切片头由reflect.SliceHeader类型表示:

    type SliceHeader struct {
            Data uintptr
            Len  int
            Cap  int
    }
    

    您可以使用包unsafe 将切片指针转换为*reflect.SliceHeader,如下所示:

    sh := (*reflect.SliceHeader)(unsafe.Pointer(&newSlice2))
    

    然后你可以像其他结构一样打印它:

    fmt.Printf("%+v", sh)
    

    输出将是(在Go Playground 上尝试):

    &{Data:1792106 Len:8 Cap:246}
    

    另请注意,您可以访问存储在切片头中的信息,而无需使用包 unsafe 和 reflect:

    • 要获取Data 字段,您可以使用&newSlice2[0]
    • 要获取Len 字段,请使用len(newSlice2)
    • 要获取Cap 字段,请使用cap(newSlice2)

    查看修改后的Go Playground 示例,该示例显示这些值与切片标头中的值相同。

    查看相关问题:

    How to create an array or a slice from an array unsafe.Pointer in golang?

    nil slices vs non-nil slices vs empty slices in Go language

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 1970-01-01
      • 2017-03-13
      • 2018-12-18
      • 1970-01-01
      • 2012-08-09
      • 2017-11-27
      • 2013-02-25
      • 2019-07-05
      相关资源
      最近更新 更多