상세 컨텐츠

본문 제목

Golang - map[string]interface{}을 활용하여 슬라이스 및 배열에 데이터 넣기 실습

Programming Language/Go

by Yongari 2023. 4. 16. 15:08

본문

Go 언어에서 map[string]interface{}란??

 

Go언어에서 map[string]interface{}는 key는 string이고 value는 어떤 타입이든 될 수 있는 map 타입을 정의하는 타입입니다. map은 파이썬에서는 딕셔너리 즉 키와 밸류로 이루어진 객체타입이죠
그렇다면 이런 타입을 왜 Go언어에서 자주? 쓸까요?? ( 제 입장에서 자주일수도 있습니다.)

 

Go언어에서 map[string]interface{}를 쓰는 이유??

 

일반적으로 Go 언어에서 map[string]interface{}를 쓰는 이유는  일반적으로 JSON 데이터를 다룰 때 사용합니다. 
예를 들어 다음과 같은 JSON 데이터가 있다고 가정해봅시다. 

{
  "name": "Alice",
  "age": 30,
  "is_student": true,
  "favorite_foods": ["pizza", "pasta"]
}

이 데이터를 Go에서 다루기 위해서 map[string]interface{}를 사용할 수 있습니다. 예를 들면 다음과 같이 Go언어에서 변수로 할당할 수 있습니다.

data := map[string]interface{}{
    "name":          "Alice",
    "age":           30,
    "is_student":    true,
    "favorite_foods": []string{"pizza", "pasta"},
}

 

 

좀 더 복잡한 타입도 가능합니다.

OpenSea의 NFT Metadata Standard에 있는 데이터를 Go의 슬라이스에 넣는 방법

예를 들어 다음과 같은 식으로도 데이터 저장이 가능합니다. (open sea의 NFT 메타데이터 스탠다드에 있는 데이터를 변수로 활용했습니다.)

	data := map[string]interface{}{
		"attributes": []map[string]string{
			{"trait_type": "location", "name": "런던", "value": "뉴욕"},
			{"trait_type": "latitude", "value": "51.5072"},
			{"trait_type": "longitude", "value": "-0.1275"},
		},
		"description": "cloud",
		"image":       "https://gateway.ipfscdn.io/ipfs/QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png",
		"name":        "cloud",
	}



string들은 전부 객체이지만 attributes를 보면 value에 []map[string]string이 왔습니다. 이 안의 객체또한 또 저장할 수 있는 것입니다. 이런 데이터를 슬라이스에 넣고 각각 원소 사이에 " , "를 넣어보겠습니다.

 

package main

import (
	"fmt"
	"reflect"
	"strings"
)

func main() {
	//map[string]interface{}
	//go언어의 특성상 string은 key값으로 interface는 여러 값을 밸류로 쓸 수 있게 하기 위해 사용함

	data := map[string]interface{}{
		"attributes": []map[string]string{
			{"trait_type": "location", "name": "런던", "value": "뉴욕"},
			{"trait_type": "latitude", "value": "51.5072"},
			{"trait_type": "longitude", "value": "-0.1275"},
		},
		"description": "cloud",
		"image":       "https://gateway.ipfscdn.io/ipfs/QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png",
		"name":        "cloud",
	}

	var elements []string
	fmt.Println("elements", elements)
	fmt.Println(reflect.TypeOf(elements))
	fmt.Println("data", data)
	fmt.Println("type of", reflect.TypeOf(data))

	for k, v := range data {
		element := k + ":"
		switch v := v.(type) {
		case string:
			fmt.Println("string", element)
			element += v
		case []map[string]string:

			for _, m := range v {
				for k, s := range m {
					fmt.Println("map[string]string", element)
					element += k + ":" + s + " "
				}
			}
		}
		elements = append(elements, element)
		fmt.Println("elements", elements)
	}
	result := "[" + strings.Join(elements, ",") + "]"

	fmt.Println("result", result)

}

 

그리고 이 소스코드를 컴파일하고 실행하면 다음과 같습니다.
각 데이터가 출력되는 Flow를 보시면 흐름을 알 수 있습니다. 

go build make_mapStringInterface_slice.go 
robertseo@robertseo-HP-17T-Notebook-PC:~/work/golang/basic/slice$ ./make_mapStringInterface_slice 
elements []
[]string
data map[attributes:[map[name:런던 trait_type:location value:뉴욕] map[trait_type:latitude value:51.5072] map[trait_type:longitude value:-0.1275]] description:cloud image:https://gateway.ipfscdn.io/ipfs/QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png name:cloud]
type of map[string]interface {}
string name:
elements [name:cloud]
map[string]string attributes:
map[string]string attributes:trait_type:location 
map[string]string attributes:trait_type:location name:런던 
map[string]string attributes:trait_type:location name:런던 value:뉴욕 
map[string]string attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude 
map[string]string attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 
map[string]string attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude 
elements [name:cloud attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275 ]
string description:
elements [name:cloud attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275  description:cloud]
string image:
elements [name:cloud attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275  description:cloud image:https://gateway.ipfscdn.io/ipfs/QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png]
result [name:cloud,attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275 ,description:cloud,image:https://gateway.ipfscdn.io/ipfs/QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png]

 

 

위와 비슷한 형태로 이번에는 Slice가 아닌 배열에 데이터를 넣어보겠습니다. 

로직은 동일합니다만 조금 문법형태가 다릅니다.

package main

import (
	"fmt"
	"strings"
)

func main() {
	data := map[string]interface{}{
		"attributes": []map[string]string{
			{"trait_type": "location", "name": "런던", "value": "뉴욕"},
			{"trait_type": "latitude", "value": "51.5072"},
			{"trait_type": "longitude", "value": "-0.1275"},
		},
		"description": "cloud",
		"image":       "ipfs://QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png",
		"name":        "cloud",
	}
	//배열을 이용한 구현
	var elements [4]string
	i := 0
	for key, value := range data {
		element := key + ":"
		fmt.Println("element", element)
		switch v := value.(type) {
		case string:
			element += v
			fmt.Println("case string : ", element)
		case []map[string]string:
			for _, m := range v {
				for k, s := range m {
					element += k + ":" + s + " "
					fmt.Println("case []map[string]string : ", element)
				}
			}
		}
		elements[i] = element
		i++
		fmt.Println("elements : ", elements)
	}
	result := "[" + strings.Join(elements[:], ",") + "]"
	fmt.Println("result", result)

}

그리고 이 소스코드를 컴파일하고 실행하면 다음과 같습니다.
각 데이터가 출력되는 Flow를 보시면 흐름을 알 수 있습니다.  Slice와 유사합니다.

go run mapStringInterface_array.go 
element attributes:
case []map[string]string :  attributes:trait_type:location 
case []map[string]string :  attributes:trait_type:location name:런던 
case []map[string]string :  attributes:trait_type:location name:런던 value:뉴욕 
case []map[string]string :  attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude 
case []map[string]string :  attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 
case []map[string]string :  attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude 
case []map[string]string :  attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275 
elements :  [attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275    ]
element description:
case string :  description:cloud
elements :  [attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275  description:cloud  ]
element image:
case string :  image:ipfs://QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png
elements :  [attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275  description:cloud image:ipfs://QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png ]
element name:
case string :  name:cloud
elements :  [attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275  description:cloud image:ipfs://QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png name:cloud]
result [attributes:trait_type:location name:런던 value:뉴욕 trait_type:latitude value:51.5072 trait_type:longitude value:-0.1275 ,description:cloud,image:ipfs://QmSK8392GF11ZJ3vnpLiSvx1ciE7B5d7UT27ctkLwNa79x/goku3.png,name:cloud]

 

관련글 더보기