Created
April 22, 2022 08:24
-
-
Save CAFxX/8d66e8608dfdfdc0be2756182d56eddd to your computer and use it in GitHub Desktop.
reflect.SliceHeader and reflect.StringHeader examples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package reflect_test | |
// Extracted from https://go-review.googlesource.com/c/go/+/401434 | |
import ( | |
"fmt" | |
"reflect" | |
"unsafe" | |
) | |
func ExampleStringHeader() { | |
src := "Hello World!" | |
var dst string | |
// The code in this example shows the correct way of using StringHeader by | |
// obtaining a pointer to the string's header and then using the pointer to | |
// read/write the header fields. | |
// | |
// On the contrary, all of the following are NOT correct and must NOT be used: | |
// | |
// var s string | |
// *(*reflect.StringHeader)(unsafe.Pointer(&s)) = reflect.StringHeader{ | |
// Data: /* ... */, Len: /* ... */, | |
// } | |
// | |
// s := *(*string)(unsafe.Pointer(&reflect.StringHeader{ | |
// Data: /* ... */, Len: /* ... */, | |
// })) | |
// | |
// var sh reflect.StringHeader | |
// sh.Data, sh.Len = /* ... */ | |
// s := *(*string)(unsafe.Pointer(&sh)) | |
// | |
// go vet attempts to identify and report suspicious uses of reflect.StringHeader. | |
// See https://github.com/golang/go/issues/40701 for more details. | |
srcHdr := (*reflect.StringHeader)(unsafe.Pointer(&src)) | |
dstHdr := (*reflect.StringHeader)(unsafe.Pointer(&dst)) | |
// Equivalent to dst = src[6:6+5], but without bounds checks! | |
dstHdr.Data = srcHdr.Data + 6 | |
dstHdr.Len = 5 | |
runtime.KeepAlive(src) // Ensure src is not GCed prematurely. | |
fmt.Println(dst) | |
// Output: | |
// World | |
} | |
func ExampleSliceHeader() { | |
src := []byte("Hello World!") | |
var dst []byte | |
// The code in this example shows the correct way of using SliceHeader by | |
// obtaining a pointer to the slice's header and then using the pointer to | |
// read/write the header fields. | |
// | |
// On the contrary, all of the following are NOT correct and must NOT be used: | |
// | |
// var s []byte | |
// *(*reflect.SliceHeader)(unsafe.Pointer(&s)) = reflect.SliceHeader{ | |
// Data: /* ... */, Len: /* ... */, Cap: /* ... */, | |
// } | |
// | |
// s := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ | |
// Data: /* ... */, Len: /* ... */, Cap: /* ... */, | |
// })) | |
// | |
// var sh reflect.SliceHeader | |
// sh.Data, sh.Len, sh.Cap = /* ... */ | |
// s := *(*[]byte)(unsafe.Pointer(&sh)) | |
// | |
// go vet attempts to identify and report suspicious uses of reflect.SliceHeader. | |
// See https://github.com/golang/go/issues/40701 for more details. | |
srcHdr := (*reflect.SliceHeader)(unsafe.Pointer(&src)) | |
dstHdr := (*reflect.SliceHeader)(unsafe.Pointer(&dst)) | |
// Equivalent to dst = src[6:6+5:6+5], but without bounds checks! | |
dstHdr.Data = srcHdr.Data + 6 | |
dstHdr.Len = 5 | |
dstHdr.Cap = 5 | |
runtime.KeepAlive(src) // Ensure src is not GCed prematurely. | |
fmt.Println(string(dst)) | |
// Output: | |
// World | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment