Please take a look at the following code:
```go
package main
import (
"fmt"
"runtime"
"unsafe"
)
func assert(b bool) {
if b {
} else {
panic("unexpected")
}
}
type Elementer interface {
GetInt64Slice() []int64
GetByteSlice() []byte
String() string
}
type Element1 struct {
int64s []int64
bs []byte
}
func newElement1(int64Sz, bsSz int) *Element1 {
assert(int64Sz > 0 && bsSz > 0)
len0 := int64Sz * 8
len1 := bsSz
buf := make([]byte, len0+len1)
for i := range buf {
buf[i] = byte(i)
}
e := &Element1{
int64s: unsafe.Slice((*int64)(unsafe.Pointer(&buf[0])), int64Sz),
bs: unsafe.Slice((*byte)(&buf[len0]), bsSz),
}
return e
}
func (e *Element1) GetInt64Slice() []int64 {
return e.int64s
}
func (e *Element1) GetByteSlice() []byte {
return
e.bs}
func (e *Element1) String() string {
return fmt.Sprintf("Element1:[% x % x]", e.GetInt64Slice(), e.GetByteSlice())
}
type Element2 struct {
underlyBuf []byte // <- is this field needed?
int64s []int64
bs []byte
}
func newElement2(int64Sz, bsSz int) *Element2 {
assert(int64Sz > 0 && bsSz > 0)
len0 := int64Sz * 8
len1 := bsSz
buf := make([]byte, len0+len1)
for i := range buf {
buf[i] = byte(i)
}
e := &Element2{
underlyBuf: buf, // <-
int64s: unsafe.Slice((*int64)(unsafe.Pointer(&buf[0])), int64Sz),
bs: unsafe.Slice((*byte)(&buf[len0]), bsSz),
}
return e
}
func (e *Element2) GetInt64Slice() []int64 {
runtime.KeepAlive(e.underlyBuf)
return e.int64s
}
func (e *Element2) GetByteSlice() []byte {
runtime.KeepAlive(e.underlyBuf)
return
e.bs}
func (e *Element2) String() string {
runtime.KeepAlive(e.underlyBuf)
return fmt.Sprintf("Element2:[% x % x]", e.GetInt64Slice(), e.GetByteSlice())
}
func main() {
var e Elementer
fmt.Println("print with host endian:")
e = newElement1(2, 4)
fmt.Println("hi", e)
e = newElement2(2, 4)
fmt.Println("hi", e)
}
```
And which yields:
```
hi Element1:[[ 706050403020100 f0e0d0c0b0a0908] 10 11 12 13]
hi Element2:[[ 706050403020100 f0e0d0c0b0a0908] 10 11 12 13]
```
I'm not sure whether the `underlyBuf` filed in `Element2` is needed or not. When I'm reading the doc from `
https://pkg.go.dev/reflect#SliceHeader` there is:
> Moreover, the Data field is not sufficient to guarantee the data it references will not be garbage collected, so programs must keep a separate, correctly typed pointer to the underlying data.
But in `
https://pkg.go.dev/unsafe#Slice` there are no such comments. So the question:
Which implementation of `Elementer` is correct? `Element2` or both of them?
Thanks a lot for your help.