Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pergi - Tukar penuding kepada kepingan struktur kepada kepingan antara muka

Pergi - Tukar penuding kepada kepingan struktur kepada kepingan antara muka

WBOY
WBOYke hadapan
2024-02-09 14:57:081062semak imbas

Go - 将指向结构切片的指针转换为接口切片

editor php Baicao Dalam bahasa pengaturcaraan Go, kadangkala kita perlu menukar penunjuk untuk menstruktur kepingan menjadi kepingan antara muka. Penukaran ini sangat berguna dalam beberapa situasi tertentu, seperti apabila kita perlu mengubah suai elemen dalam kepingan. Dengan menukar penunjuk kepada kepingan antara muka, kami boleh mengakses dan mengubah suai elemen dengan mudah dalam kepingan tanpa perlu risau tentang ketekalan data dan isu penyegerakan. Dalam artikel ini, kami akan menerangkan cara membuat penukaran ini dan memberikan beberapa contoh aplikasi praktikal.

Kandungan soalan

Saya memotong beberapa kod GoLang pengeluaran untuk mencipta contoh berikut:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var aData []AlphaStruct
    var bData []BetaStruct

    readData(&aData)
    readData(&bData)

    // Do other stuff with the loaded structures.
}

func readData(structSlicePointer any) {
    json.Unmarshal([]byte(
        "["+
            "{\"name\": \"John Smith\"},"+
            "{\"name\": \"Jane Doe\"}"+
            "]"),
        structSlicePointer)

    var initializers []Initializer

    // At this point I want to do:
    // initializers = structSlicePointer
    // However I can't find any type declarations or casts that will work with the rest of the code.

    for _, initializer := range initializers {
        initializer.Initialize()
    }
}

type Initializer interface {
    Initialize()
}

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

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

func (es *AlphaStruct) Initialize() {
    fmt.Printf("In Alpha: %s\n", es.Name)
}

func (es *BetaStruct) Initialize() {
    fmt.Printf("In Beta: %s\n", es.Name)
}

Saya mempunyai banyak struct dan semuanya melaksanakan antara muka yang sama.

Ideanya ialah selepas menyahsiri mereka (dari JSON) saya ingin memanggil kaedah pada setiap objek yang dimuatkan untuk melengkapkan pemulaan objek. Sesetengah fail JSON mempunyai tatasusunan peringkat atas - iaitu setelah dinyahsiri, ia adalah senarai/kepingan struktur.

Walau bagaimanapun, saya tidak menemui sebarang kombinasi pernyataan yang membolehkan saya melakukan perkara berikut secara serentak:

  • Laksanakan json.Unmarshal()
  • Lelaran setiap struktur yang dimuatkan dan kaedah panggilan.

Jelas sekali, saya boleh membahagikannya kepada dua fungsi (loadData dan initializeData) untuk melaksanakan kedua-dua fungsi.

Adakah terdapat sebarang cara untuk menstruktur semula ini supaya ia berfungsi sebagai satu kaedah?

Penyelesaian

Anda boleh mengisytiharkan kaedah sebagai kaedah generik yang menerima kepingan struct dengan ahli yang melaksanakan antara muka Initializer.

Untuk melakukan ini, anda boleh mengisytiharkan kaedah anda seperti ini:

func readData[T Initializer](structSlicePointer *[]T) {
    json.Unmarshal(
        []byte("[{\"name\": \"John Smith\"},{\"name\": \"Jane Doe\"}]"),
        structSlicePointer,
    )
    for _, initializer := range *structSlicePointer {
        initializer.Initialize()
    }
}

Perhatikan bahawa ini memerlukan anda mengisytiharkan nilai hirisan sebagai penunjuk untuk digunakan dengan kaedah penerima penunjuk pada struktur (cth. []*AlphaStruct[]AlphaStruct):

func main() {
    var aData []*AlphaStruct
    var bData []*BetaStruct

    readData(&aData)
    readData(&bData)
}

Keluaran:

In Alpha: John Smith
In Alpha: Jane Doe
In Beta: John Smith
In Beta: Jane Doe

Atas ialah kandungan terperinci Pergi - Tukar penuding kepada kepingan struktur kepada kepingan antara muka. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam