I have the following function. I want to return the *string via the object interface{} parameter. If json.Unmarshal succeeds then it manages to return valid data, but I can't seem to.
I tried a bunch of variations but still it's coming out blank from the calling function. Although the type showing on the outside for the object is "string*", although it's empty. How can I do this?
My actual code below. But, for simplicity here an even simpler version.
https://go.dev/play/p/nnsKZxvU42M
// UnmarshalObject decodes an object from binary data
func UnmarshalObject(data []byte, object interface{}) error {
err := json.Unmarshal(data, object)
if err != nil {
s := string(data)
object = &s
}
return nil
}
It's being called like this
func (connection *DbConnection) GetObject(bucketName string, key []byte, object interface{}) error {
// ...
err = UnmarshalObject(data, object)
return err
}
From this function
// DBVersion retrieves the stored database version.
func (service *Service) DBVersion() (int, error) {
var version string
err := service.connection.GetObject(BucketName, []byte(versionKey), &version)
if err != nil {
return 0, err
}
return strconv.Atoi(version)
}
In this case, Atoi fails because version is ""
CodePudding user response:
Generally, use a type-switch to check if the interface is any of your expected types.
func UnmarshalObject(data []byte, object interface{}) error {
err := json.Unmarshal(data, object)
if err {
return error;
}
switch object.(type) {
case string:
// object is a string
case int:
// object is an integer
default:
// object is something you did not expect.
return fmt.Errorf("Unknown type %T", v)
}
return nil;
}
CodePudding user response:
I figured it out and learned something along the way. This form works.
// UnmarshalObject decodes an object from binary data
func UnmarshalObject(data []byte, object interface{}) error {
err := json.Unmarshal(data, object)
if err != nil {
if s, ok := object.(*string); !ok {
return err
}
*s = string(data)
}
return nil
}