Pergi - Tukar penuding kepada kepingan struktur kepada kepingan antara muka

WBOY
Lepaskan: 2024-02-09 14:57:08
ke hadapan
1107 orang telah melayarinya

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)
}
Salin selepas log masuk

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()
    }
}
Salin selepas log masuk

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)
}
Salin selepas log masuk

Keluaran:

In Alpha: John Smith
In Alpha: Jane Doe
In Beta: John Smith
In Beta: Jane Doe
Salin selepas log masuk

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!

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