简体   繁体   English

为什么 Golang string.Builder String() 可以在没有 reflect.StringHeader 的情况下将 []byte 转换为 slice?

[英]Why Golang string.Builder String() can convert []byte to slice without a reflect.StringHeader?

Go's strings package defines a Builder type which has a String() method Go 的字符串 package 定义了一个具有 String() 方法的 Builder 类型

func (b *Builder) String() string {
    return *(*string)(unsafe.Pointer(&b.buf))
}

as reflect pacakge indicates, a byte slice is defined as a SliceHeader and an associated data block pointed by the header's Data field:正如 reflect pacakge 所指出的,一个字节切片被定义为一个 SliceHeader 和一个由 header 的 Data 字段指向的关联数据块:

type SliceHeader struct {
  Data uintptr
  Len  int
  Cap  int
}

and string is defined as a StringHeader and an associated data block pointed by the header's Data field并且 string 被定义为一个 StringHeader 和一个由 header 的 Data 字段指向的关联数据块

type StringHeader struct {
  Data uintptr
  Len  int
}

the SliceHeader has 3 fields(Data, Len and Cap) and StringHeader has only 2(Data and Len), so how can one convert byte slice to string directly like this? SliceHeader 有 3 个字段(Data、Len 和 Cap)而 StringHeader 只有 2 个(Data 和 Len),那么如何像这样直接将字节切片转换为字符串呢?

*(*string)(unsafe.Pointer(&buf))

in my understanding, we should code following:据我了解,我们应该编写以下代码:

func byte2str(b []byte) string {
  hdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
  return *(*string)(unsafe.Pointer(&reflect.StringHeader{Data: hdr.Data, Len: hdr.Len}))
}

Let's break it down.让我们分解一下。

The expression &buf is a pointer to the slice header.表达式&buf是指向切片 header 的指针。 A pointer to a slice is a pointer to the slice header.指向切片的指针是指向切片 header 的指针。

The expression (unsafe.Pointer(&buf) is a conversion from the slice header pointer to an unsafe.Pointer . The unsafe.Pointer type has magical a magical property -- it can be converted to and from any other pointer type.表达式(unsafe.Pointer(&buf)是从切片 header 指针到unsafe.Pointer的转换。unsafe.Pointer 类型具有神奇的神奇属性——它可以与任何其他指针类型相互转换。

The expression is (*string)(unsafe.Pointer(&buf)) is a conversion from a slice header pointer to a string header pointer (a pointer to a string is a pointer to the header).表达式是(*string)(unsafe.Pointer(&buf))是从切片 header 指针到字符串 header 指针的转换(指向字符串的指针是指向标头的指针)。

The expression *(*string)(unsafe.Pointer(&buf)) dereferences the string header pointer to get the string.表达式*(*string)(unsafe.Pointer(&buf))取消引用字符串 header 指针以获取字符串。

This all works because the the memory layout of a string header is a prefix of the memory layout for a slice header.这一切都有效,因为字符串 header 的 memory 布局是 memory 布局 Z09749FB9953446F0DEF31 切片的前缀。 The final dereference of the string header pointer copies the two string header fields only.字符串 header 指针的最终取消引用仅复制两个字符串 header 字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM