I need to create struct with generics with dynamic tags
e.g. We have one struct with generics
Phone[T]
and simple structCompany
So Phone can belongs to Company and that means our type would be Phone[Company]
type Company struct{}
type Phone[T any] struct{
number string `json:"phone_number"`
}
Lets create new variable Phone[Company]
phone1 := Phone[Company]{
number: " 18888888888"
}
Output of serialized phone1
is
{
"phone_number": " 18888888888"
}
Question
How to set struct Phone[T]
type field tags dynamically to receive json like company_phone_number
instead of phone_number
?
How can i use generic types in golang tags?
e.g.
type Phone[T any] struct{
number string `json:"${T or replica name of T type e.t.c}_phone_number"`
}
CodePudding user response:
You can do it only if you rebuild your struct on-the-fly with reflect. There is a package for this (I didn't try it) here.
But instead I recommend you to write a custom MarshalJSON method for the struct which handles the cases based on the type of the variable.
package main
import (
"encoding/json"
"errors"
"fmt"
)
type Phone[T any] struct {
variableType T
Number string
}
func (p Phone[T]) MarshalJSON() ([]byte, error) {
switch any(p.variableType).(type) {
case Company:
return json.Marshal(&struct {
Number string `json:"company_phone_number"`
}{
Number: p.Number,
})
case Company2:
return json.Marshal(&struct {
Number string `json:"company2_phone_number"`
}{
Number: p.Number,
})
}
return []byte{}, errors.New("Invalid type")
}
type Company struct {
}
type Company2 struct {
}
func main() {
p := Phone[Company]{
Number: "123",
}
p2 := Phone[Company2]{
Number: "321",
}
data1, _ := json.Marshal(p)
data2, _ := json.Marshal(p2)
fmt.Println(p, string(data1))
fmt.Println(p2, string(data2))
}
If you want to avoid the switch you can get the variable type with reflect.TypeOf(p.variableType).Name()
but then you have to write a custom JSON marshaler to represent the byte slice with the custom json tags.
CodePudding user response:
It's imposible!
For your case you can redesign your architecture