Saya baru mengenali golang generik dan mempunyai persediaan berikut.
- Saya telah mengumpulkan banyak jenis laporan.
- Setiap laporan mempunyai medan yang dilampirkan
- Jadi saya membungkusnya dalam ReportContainerImpl
Saya telah menggunakan hujah jenis [T Reportable] di mana Reportable ditakrifkan seperti berikut
type Reportable interface {
ExportDataPointReport | ImportDataPointReport | MissingDataPointReport | SensorThresoldReport
}
Setiap jenis dalam kekangan jenis adalah struct yang akan dibenamkan dalam bekas.
type ReportContainerImpl[T Reportable] struct {
LocationID string `json:"lid"`
Provider string `json:"pn"`
ReportType ReportType `json:"m"`
Body T `json:"body"`
}
Saya menggunakan ReportType diskriminator untuk menentukan jenis konkrit apabila Unmarshal.
type ReportType string
const (
ReportTypeExportDataPointReport ReportType = "ExportDataPointReport"
ReportTypeImportDataPointReport ReportType = "ImportDataPointReport"
ReportTypeMissingDataPointReport ReportType = "MissingDataPointReport"
ReportTypeSensorThresoldReport ReportType = "SensorThresoldReport"
)
Memandangkan go tidak menyokong penegasan jenis untuk struct ( antara muka sahaja ) tidak mungkin untuk menghantar jenis apabila Unmarshal. Juga pergi tidak menyokong penunjuk kepada jenis generik "mentah" . Oleh itu, saya telah mencipta antara muka yang ReportContainerImpl laksanakan.
type ReportContainer interface {
GetLocationID() string
GetProvider() string
GetReportType() ReportType
GetBody() interface{}
}
Masalah yang saya dapati ialah saya tidak boleh melakukan kekangan jenis pada jenis pulangan dalam sebarang bentuk atau bentuk dan saya kembali pada "semantik teks bebas" pada fungsi GetBody() untuk membenarkan penegasan jenis apabila Unmarshal selesai.
container, err := UnmarshalReportContainer(data)
if rep, ok := container.GetBody().(ExportDataPointReport); ok {
// Use the ReportContainerImpl[ExportDataPointReport] here...
}
Mungkin saya salah faham? - tetapi walau bagaimanapun saya melakukan ini, saya sentiasa berakhir dengan suatu tempat memerlukan antara muka{} atau untuk mengetahui jenis yang tepat sebelum Unmarshal
- Adakah anda mempunyai cadangan yang lebih baik bagaimana untuk menyelesaikannya dengan cara jenis (lebih selamat)?
Tahniah, Mario :)
Untuk kesempurnaan saya menambah UnmarshalReportContainer di sini
func UnmarshalReportContainer(data []byte) (ReportContainer, error) {
type Temp struct {
LocationID string `json:"lid"`
Provider string `json:"pn"`
ReportType ReportType `json:"m"`
Body *json.RawMessage `json:"body"`
}
var temp Temp
err := json.Unmarshal(data, &temp)
if err != nil {
return nil, err
}
switch temp.ReportType {
case ReportTypeExportDataPointReport:
var report ExportDataPointReport
err := json.Unmarshal(*temp.Body, &report)
return &ReportContainerImpl[ExportDataPointReport]{
LocationID: temp.LocationID,
Provider: temp.Provider,
ReportType: temp.ReportType,
Body: report,
}, err
// ...
}
}
0 jawapan
Alat panas Tag
Soalan panas
Alat popular
vc9-vc14 (32+64 bit) koleksi perpustakaan masa jalan (pautan di bawah)
Muat turun koleksi perpustakaan runtime yang diperlukan untuk pemasangan phpStudy
VC9 32-bit
VC9 32-bit phpstudy pustaka masa jalan persekitaran pemasangan bersepadu
Kotak alat pengaturcara PHP versi penuh
Programmer Toolbox v1.0 PHP Persekitaran Bersepadu
VC11 32-bit
VC11 32-bit phpstudy pustaka masa jalan persekitaran pemasangan bersepadu
SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan
Topik panas






