I got this error:
cannot unmarshal string into Go struct field Attributes.length of type float64
but I’m trying to unmarshal the field with the lowercase letter which is indeed a number.
Why the error?
Notice the tag: json:"length", which should get me the lower case field, right?
Here is the playground, if you want to reproduce it https://go.dev/play/p/v7EWz5OGou4
import (
"encoding/json"
"fmt"
)
const problematicData = `{
"length": 3350,
"Length": "3350"
}`
type Attributes struct {
Length float64 `json:"length"`
}
func main() {
var attributes Attributes
err := json.Unmarshal([]byte(problematicData), &attributes)
fmt.Println("error:", err)
}
>Solution :
Golang’s Unmarshal function is case in-sensitive by default. See https://pkg.go.dev/encoding/json#Unmarshal
preferring an exact match but also accepting a case-insensitive match
In order to get this working in your case, you’ll need to implement a custom unmarshaller.
The following will accept the length key from the json. Playground: https://go.dev/play/p/OAUdMBc0Szi
package main
import (
"encoding/json"
"fmt"
)
const problematicData = `{
"length": 3350,
"Length": "3350"
}`
type Attributes struct {
Length float64 `json:"length"`
}
func (b *Attributes) UnmarshalJSON(data []byte) error {
var v map[string]any
if err := json.Unmarshal(data, &v); err != nil {
return err
}
for key, v := range v {
if key != "length" {
continue
}
if floatValue, ok := v.(float64); ok {
b.Length = floatValue
}
}
return nil
}
func main() {
var attributes Attributes
err := json.Unmarshal([]byte(problematicData), &attributes)
fmt.Println("error:", err, attributes)
}