That code doesn't even compile in go 1.22 or go.1.21:
https://go.dev/play/p/mPCBUQizSVo
./prog.go:20:14: cannot convert unsafe.Pointer(s) (value of type
unsafe.Pointer) to type []To
What's the underlying requirement? In the test case it looks like you want
to take a slice of int32's, in whatever their internal in-memory
representation is, and re-represent them as a slice of half as many
int64's?? Then of *course* each pair of int32's will become one int64, and
the order of the hi/lo halves will depend entirely on the system's internal
representation of int64's. It *is* working, in the sense that it's doing
exactly what you told it to do. There's a reason why the "unsafe" package
is called "unsafe"!
It would be straightforward to write a function which takes a slice
containing pairs of int32's and assembles them into int64's in a consistent
way. What you've not explained is:
- why you need to do this with generics (for example, what behaviour would
you expect from other types?)
- why you need to do this in-place with "unsafe"
On Wednesday 8 May 2024 at 10:24:30 UTC+1 Srinivas Pokala wrote:
> Hello gopher's,
>
> I have simple go program which convert slice of one type to slice of other
> type using go generics for handling all the supported types.
> Below is the code snippest for this:
> package main
>
> import "fmt"
> import "unsafe"
>
> type slice struct {
> ptr unsafe.Pointer
> len int
> cap int
> }
>
> func Slice[To, From any](data []From) []To {
> var zf From
> var zt To
> var s = (*slice)(unsafe.Pointer(&data))
> s.len = int((uintptr(s.len) * unsafe.Sizeof(zf)) /
> unsafe.Sizeof(zt))
> s.cap = int((uintptr(s.cap) * unsafe.Sizeof(zf)) /
> unsafe.Sizeof(zt))
> x := ([]To)(unsafe.Pointer(s))
> return x
> }
> func main() {
> a := make([]uint32, 4, 13)
> a[0] = 1
> a[1] = 0
> a[2] = 2
> a[3] = 0
> // 1 0 2 0
> b := Slice[int64](a)
> //Expecxted : []int64[]{0x00000000 00000001, 0x00000000 00000002}
> //Got: []int64{0x00000001 00000000, 0x00000002 0000000}
> if b[0] != 1 {
> fmt.Printf("wrong value at index 0: want=1 got=0x%x \n",
> b[0])
> }
> if b[1] != 2 {
> fmt.Printf("wrong value at index 1: want=2 got=0x%x\n",
> b[0])
> }
>
> }
>
> This is working fine on little endian architectures(amd64,arm64 etc), but
> when i run on big endian machine(s390x) it is not working , it is resulting
> wrong data
> //Expecxted : []int64[]{0x00000000 00000001, 0x00000000 00000002}
> //Got: []int64{0x00000001 00000000, 0x00000002 0000000}
> Can somepoint point me how do we write such scenario which should work on
> both little/endian platforms.
> Any leads on this?
>
> Thanks,
> Srinivas
>
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/a5b6f6fd-f3ec-4532-8579-179282610aban%40googlegroups.com.