How to Convert Map to Struct in Golang [4 Methods]

Here are the four ways to convert a map to a struct in Go.

  1. Using json.Marshal() and json.Unmarshal()
  2. Using mapstructure
  3. Using a reflect package
  4. Using for loop

Method 1: Using json.Unmarshal()

Using the json.Marshal() and json.Unmarshal() methods are provided by the encoding/json package to convert between loosely typed and strictly typed data structures.

Example

package main

import (
  "encoding/json"
  "fmt"
  "log"
)

type Person struct {
  Name string `json:"name"`
  Age int `json:"age"`
}

func main() {
  // Create a map with the same structure as the Person struct
  personMap := map[string]interface{}{
    "name": "Krunal Lathiya",
    "age": 30,
  }

  // Marshal the map into JSON data
  jsonData, err := json.Marshal(personMap)
  if err != nil {
    log.Fatal(err)
  }

  // Unmarshal the JSON data into a Person struct
  var person Person
  err = json.Unmarshal(jsonData, &person)
  if err != nil {
    log.Fatal(err)
  }

  fmt.Printf("Name: %s, Age: %d\n", person.Name, person.Age)
}

Output

Name: Krunal Lathiya, Age: 30

We converted the map into JSON data using the “json.Marshal()” function. Next, we converted the JSON data into a Person struct using the “json.Unmarshal()” function.

Finally, we printed the values of the person struct.

Method 2: Using mapstructure

Install the mapstructure package by running the following command:

go get github.com/mitchellh/mapstructure

Once the package is installed, you can use the mapstructure.Decode() method.

Example

package main

import (
  "encoding/json"
  "fmt"

  "github.com/mitchellh/mapstructure"
)

type Person struct {
  Name string `json:"name"`
  Age int `json:"age"`
  Address struct {
    City string `json:"city"`
    State string `json:"state"`
  } `json:"address"`
}

func main() {
  // JSON data
  jsonData := `{
    "name": "Krunal Lathiya",
    "age": 30,
    "address": {
       "city": "Rajkot",
       "state": "Gujarat"
     }
   }`

  // Unmarshal JSON data into a map
  var dataMap map[string]interface{}
  err := json.Unmarshal([]byte(jsonData), &dataMap)
  if err != nil {
    panic(err)
  }

  // Convert map to struct using mapstructure
  var person Person
  err = mapstructure.Decode(dataMap, &person)
  if err != nil {
    panic(err)
  }

  // Print the struct data
  fmt.Printf("Name: %s\n", person.Name)
  fmt.Printf("Age: %d\n", person.Age)
  fmt.Printf("City: %s\n", person.Address.City)
  fmt.Printf("State: %s\n", person.Address.State)
}

Output

Name: Krunal Lathiya
Age: 30
City: Rajkot
State: Gujarat

Method 3: Using reflect package

You can use the reflect package to dynamically convert a map[string]interface{} to a struct. This approach provides more flexibility than using a simple for loop but requires a deeper understanding of the Go reflection mechanism.

Example

package main

import (
  "fmt"
  "reflect"
)

type Person struct {
  Name string
  Age int
  City string
  State string
}

func main() {
  dataMap := map[string]interface{}{
    "Name": "Krunal Lathiya",
    "Age": 30,
    "City": "Rajkot",
    "State": "Gujarat",
  }

  var person Person
  convertMapToStruct(dataMap, &person)

  fmt.Printf("Name: %s\n", person.Name)
  fmt.Printf("Age: %d\n", person.Age)
  fmt.Printf("City: %s\n", person.City)
  fmt.Printf("State: %s\n", person.State)
}

func convertMapToStruct(m map[string]interface{}, s interface{}) {
  structValue := reflect.ValueOf(s).Elem()
  structType := structValue.Type()

  for i := 0; i < structValue.NumField(); i++ {
    field := structValue.Field(i)
    fieldType := structType.Field(i)
    fieldName := fieldType.Name

    if val, ok := m[fieldName]; ok {
      field.Set(reflect.ValueOf(val))
    }
  }
}

Output

Name: Krunal Lathiya
Age: 30
City: Rajkot
State: Gujarat

In this code, we defined a Person struct and a dataMap with some data.

In the next step, we used the convertMapToStruct function to convert the map to a struct. This function iterates through the fields of the struct using reflection and sets their values based on the corresponding map entries.

Method 4: Using a for loop

This approach doesn’t require external libraries, but it’s less flexible and maintainable than using the mapstructure package or json.Unmarshal() method.

Example

package main

import (
  "fmt"
)

type Person struct {
  Name string
  Age int
  City string
  State string
}

func main() {
  dataMap := map[string]interface{}{
    "name": "Krunal Lathiya",
    "age": 30,
    "city": "Rajkot",
    "state": "Gujarat",
  }

  var person Person

  for key, value := range dataMap {
    switch key {
      case "name":
        person.Name = value.(string)
      case "age":
        person.Age = value.(int)
      case "city":
        person.City = value.(string)
      case "state":
        person.State = value.(string)
    }
  }

  fmt.Printf("Name: %s\n", person.Name)
  fmt.Printf("Age: %d\n", person.Age)
  fmt.Printf("City: %s\n", person.City)
  fmt.Printf("State: %s\n", person.State)
}

Output

Name: Krunal Lathiya
Age: 30
City: Rajkot
State: Gujarat

We iterated over the map using a for loop and a switch statement to assign the values to the corresponding struct fields.

Based on your requirements, you can use one approach from any of those mentioned above.