mercredi 14 juillet 2021

Copy slice with reflect and usafe package

I understand that usage of usafe package of golang is unsafe, but I'm doing it only for education purposes.

The idea is to copy a slice field of structure, copy it with reflect package and unsafe.pointer, modify and replace the original slice with new one.

And it looks like new slice is created and has correct capacity/length, and it contains an instance of GoodForSale type. But all fields of that instance (Name, Price and Qnty) have wrong values. So I suppose that I'm doing something wrong with pointers and getting garbade data:

package main

import (
    "fmt"
    "reflect"
    "unsafe"
)

type GoodForSale struct {
    Name string
    Price int
    Qnty int
}

type Lead struct {
    ID int
    Name string
    ContactName string
    Budget int
    Items []GoodForSale
    DateTime string
    Status int
    Win bool
}

func main()  {
    lead := &Lead{
        ID:          41,
        Name:        "Phone",
        ContactName: "John Smith",
        Budget:      30000,
        Items:       []GoodForSale{
            {
                Name:  "Iphone 6",
                Price: 100,
                Qnty:  3,
            },
        },
        DateTime:    "12.08.2020 11:23:10",
        Status: 150,
        Win:         false,
    }


    //Change Items
    pt1 := unsafe.Pointer(&lead.Items)
    copyItems := &reflect.SliceHeader{
        Data: uintptr(pt1),
        Cap: cap(lead.Items),
        Len: len(lead.Items),
    }


    items := *(*[]GoodForSale)(unsafe.Pointer(copyItems))
    fmt.Println(items[0].Name)

}

It looks like I'm missing something about how pointers work here. But how can I make this idea work correct?

Here is a go playground url: https://play.golang.org/p/SKtJWe9RVEU





Aucun commentaire:

Enregistrer un commentaire