Generic Use in Unmarshal (Go 1.18)
When utilizing generics in Go 1.18, such as creating a container to hold various report types, type constraints can arise. Consider the following setup:
You may encounter challenges with type constraints on return types, leading to "freetext semantics" in the GetBody() function to accommodate type assertion.
Challenges and Solutions
The issue stems from Go not supporting type assertions for structs and not allowing pointers to generic types. To address this, you can create an interface that implements Getters for the LocationID, Provider, ReportType, and Body. However, this solution requires sacrificing type safety.
A safer approach involves forgoing parametric polymorphism and utilizing a concrete switch statement based on the discriminator value during JSON unmarshalling. This ensures that the correct concrete type is used for each report type.
Alternative Approach
For dynamic JSON parsing, you can employ a generic unmarshal function:
func unmarshalAny[T any](bytes []byte) (*T, error) {
out := new(T)
if err := json.Unmarshal(bytes, out); err != nil {
return nil, err
}
return out, nil
}
While this function offers flexibility, it is essential to note that if its implementation is minimal, it merely performs the same actions as inlining the unmarshalling logic directly. Thus, using this function is only justified if it introduces additional logic.
In summary, carefully consider the necessity of generics when working with concrete types and JSON unmarshalling. Opt for a switch-based solution when necessary without compromising type safety, and exercise caution when employing generic functions that unnecessarily duplicate functionality.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3