Bagaimana untuk menggunakan reflect.NewAt pada antara muka{}?

WBOY
Lepaskan: 2024-02-09 14:00:24
ke hadapan
922 orang telah melayarinya

Bagaimana untuk menggunakan reflect.NewAt pada antara muka{}?

Editor PHP Xinyi memperkenalkan anda cara menggunakan reflect.NewAt pada antara muka{}. reflect.NewAt ialah fungsi perpustakaan pantulan dalam bahasa Go, digunakan untuk mencipta tika baharu pada jenis antara muka tertentu. Dengan menggunakan reflect.NewAt, kami boleh mencipta dan memulakan contoh antara muka baharu secara dinamik tanpa menyatakan jenis tertentu pada masa penyusunan. Ini memberikan kita lebih fleksibiliti dan dinamik, membolehkan kod menjadi lebih serba boleh dan boleh diperluaskan. Yang berikut akan memberi anda penjelasan terperinci tentang cara menggunakan reflect.NewAt untuk mencipta tika pada antara muka{}.

Isi soalan

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
    "unsafe"
)

type Stu struct {
    Name string `json:"name"`
}

func MakeStu() interface{} {
    return Stu{
        Name: "Test",
    }
}

func main() {
    jsonData := []byte(`{"name":"New"}`)
    t1 := MakeStu()
    t2 := MakeStu()
    t3 := MakeStu()

    json.Unmarshal(jsonData, &t1)
    fmt.Println(t1) //Type of t1 becomes map[string]interface{} instead of struct Stu

    newPointer := reflect.New(reflect.ValueOf(t2).Type()).Interface()
    json.Unmarshal(jsonData, newPointer)
    fmt.Println(newPointer) //It works,but it need allocate memory to hold temp new variable

    brokenPointer := reflect.NewAt(reflect.ValueOf(t3).Type(), unsafe.Pointer(&t3)).Interface()
    json.Unmarshal(jsonData, brokenPointer)
    fmt.Println(brokenPointer) // I want to get the pointer of original type based on the existed variable t3,but it crashes.
}
Salin selepas log masuk

Jika saya tidak tahu jenis antara muka tertentu{} semasa pengekodan, saya tidak boleh menggunakan antara muka.(taip) untuk menghantar. Jadi bagaimana untuk menggunakan reflect.newat pada antara muka{}?

Jika terdapat antara muka yang mengandungi kaedah yang mengembalikan antara muka{}, jenis khususnya ialah struct, tetapi saya tidak dapat menentukan jenis struct semasa mengekod. Saya perlu menggunakan json.unmarshal untuk menyahkod data yang dikodkan oleh json. Saya tidak mahu mendapatkan map[string]interface{} , jadi saya perlu menetapkan jenis penerima kepada penuding kepada jenis antara muka konkrit{} . Menggunakan reflect.new adalah mudah, tetapi menggunakan memori tambahan, jadi saya ingin tahu cara menggunakan reflect.newat dengan antara muka sedia ada{}.

Penyelesaian

Saya ingin menghabiskan beberapa perkataan untuk menerangkan masalah itu.

Fungsi kita tiada kawalan makestu() 返回空接口 - 不是具体类型。这将使具体类型对 json.unmarshal() “不可见”,并且 json.unmarshal() 将其视为空接口,而不是具体类型 stu. Kita perlu menyampaikan jenis konkrit kepada unmarshaller entah bagaimana.

Saya akan menyelesaikan masalah ini dengan suis jenis:

func main() {
    jsondata := []byte(`{"name":"new"}`)
    t1 := makestu()

    switch c := t1.(type) {
    default:
        _ = json.unmarshal(jsondata, &c)
        t1 = c
    }

    fmt.println(t1)
}
Salin selepas log masuk
Suis

jenis menukar antara muka kosong kepada jenis konkrit dan json.unmarshal() menganggapnya sebagai jenis konkrit. Anda mungkin masih mempunyai peruntukan tambahan, tetapi kod itu lebih mudah dibaca dan anda tidak bergantung pada refleksi.

Jika saya berasa sangat mencabar, saya akan menambah fungsi pembantu yang menerima penuding kepada antara muka nol, seperti ini:

func unmarshal(data []byte, i *interface{}) (err error) {
    switch c := (*i).(type) {
    default:
        err = json.unmarshal(data, &c)
        *i = c
    }

    return err
}
Salin selepas log masuk

Ini akan membolehkan penggunaan seperti ini:

    jsonData := []byte(`{"name":"New"}`)
    t1 := MakeStu()
    unmarshal(jsonData, &t1)
Salin selepas log masuk

Ini kelihatan bersih kepada saya dan tidak melibatkan refleksi, tetapi ia tidak menggunakan reflect.newat() seperti yang anda sendiri cadangkan. Saya harap anda mendapati nasihat saya masih berguna.

Atas ialah kandungan terperinci Bagaimana untuk menggunakan reflect.NewAt pada antara muka{}?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!