简介
在日常的开发中,经常需要进行数据类型的类型(例如:将 struct 转换为 map 类型等),在遇到类型的转换的时候,大部分人都会有有没有库方法或需要自己去编写转换逻辑的疑问?以下通过介绍常用的类型之间相互转换的方法,来解答困惑。
常见类型转换
struct 类型与 interface{} 类型相互转换
-
interface{} 类型转换为 struct 类型
通过 x.(T) 进行类型的转换
// Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } // InterfaceToStruct interface 类型转换为 struct 类型 func InterfaceToStruct(i interface{}) error { // Interface to Struct event, ok := i.(Event) if !ok { return fmt.Errorf("interface:%+v to struct:%T fail", i, Event{}) } fmt.Printf("interface:%+v to struct:%+v", i, event) return nil } -
interface{} 类型转换为 struct 类型
interface{}可以代表任意类型,则可以直接将struct赋值给interface{}类型进行类型的转换
package main import ( "fmt" ) // Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } func main() { event := Event{ ID: "001", Name: "Interface to Struct", } // struct to interface var i interface{} = event fmt.Printf("struct:%+v to interface:%+v", event, i) }
struct 类型与 map 类型相互转换
-
struct 类型转换为 map 类型
使用第三方库
利用第三方开源库(github.com/fatih/struc… 进行转换
// Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } var event = Event{ ID: "001", Name: "struct to map", } // struct to map m := structs.Map(event)自己实现
利用反射遍历 struct 的 key 和 value,并将其赋值到 map 数据结构中
// Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } // StructToMap struct 类型转换为 map 类型 func StructToMap(s interface{}) map[string]interface{} { if s == nil { return nil } m := make(map[string]interface{}) t := reflect.TypeOf(s) v := reflect.ValueOf(s) for k := 0; k < t.NumField(); k++ { m[t.Field(k).Name] = v.Field(k).Interface() } return m } var event = Event{ ID: "001", Name: "struct to map", } // struct to map m := StructToMap(event) -
map 类型转换为 struct 类型
使用第三方库
利用第三方库(github.com/mitchellh/m… ,进行转换
// Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } var m = map[string]string{ "id": "001", "name": "map to struct", } var event Event // map to struct mapstructure.Decode(m, &event)自己实现
通过遍历 map 的 key 和 value,利用反射进行 struct 的赋值
// Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } // MapToStruct Map 数据类型转换为 Struct 数据类型 func MapToStruct(m map[string]interface{}, s interface{}) error { structValue := reflect.ValueOf(s).Elem() for mKey, mValue := range m { structFieldValue := structValue.FieldByName(mKey) if !structFieldValue.IsValid() { return fmt.Errorf("no such field:%s in struct:%+v", mKey, s) } if !structFieldValue.CanSet() { return fmt.Errorf("cannot set field mValue:%s, in struct:%+v", mKey, s) } if structFieldValue.Type() != reflect.ValueOf(mValue).Type() { return fmt.Errorf("map value type didn't match struct field type") } structFieldValue.Set(reflect.ValueOf(mValue)) } return nil } var m = map[string]interface{}{ "ID": "001", "Name": "map to struct", } var event Event if err := MapToStruct(m, &event); err != nil { fmt.Printf("map to struct err:%+v.", err) }
Struct 类型与 Json 类型相互转换
-
Struct 类型转换为 Json 类型
通过基础库 encoding/json 的 Marshal 方法,将 struct 类型转换为 json 类型
package main import ( "encoding/json" "fmt" ) // Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } func main() { event := &Event{ ID: "001", Name: "struct to json", } // struct to json b, err := json.Marshal(event) if err != nil { fmt.Errorf("struct:%+v to json err:%+v", event, err) } fmt.Printf("struct to json result:%+v.", string(b)) } -
Json 类型转换为 Struct 类型
通过基础库 encoding/json 的 Unmarshal 方法,将 json 类型转换为 struct 类型
package main import ( "encoding/json" "fmt" ) // Event 事件结构体 type Event struct { ID string `json:"id"` Name string `json:"name"` } func main() { jsonStr := `{"id": "001", "name": "Json to Struct"}` var event Event // json to struct if err := json.Unmarshal([]byte(jsonStr), &event); err != nil { fmt.Errorf("json:%+v to struct err:%+v", event, err) } fmt.Printf("json to struct result:%+v", event) }
Map 类型转换与 Json 类型相互转换
-
Json 类型转换为 Map 类型
通过基础库 encoding/json 的 Marshal 方法,将 Map 类型转换为 Struct 类型
package main import ( "encoding/json" "fmt" ) func main() { event := map[string]interface{}{ "id": "001", "name": "Map to Json", } // map to json b, err := json.Marshal(event) if err != nil { fmt.Errorf("map:%+v to json err:%+v", event, err) } fmt.Printf("map to json result:%+v", string(b)) } -
Map 类型转换为 Json 类型
通过基础库 encoding/json 的 Unmarshal 方法,将 json 类型转换为 map 类型
package main import ( "encoding/json" "fmt" ) func main() { jsonStr := `{"id": "001", "name": "Json to Struct"}` var event map[string]interface{} // json to map if err := json.Unmarshal([]byte(jsonStr), &event); err != nil { fmt.Errorf("json:%+v to map err:%+v", event, err) } fmt.Printf("json to map result:%+v", event) }
interface{} 类型与 string 类型相互转换
- interface{} 类型转换为 string 类型 将 interface{} 类型转换为 string 类型,分以下两种情况
情况1: interface{} 原始数据类型为 string 类型,转换为 string 类型,则通过x.(T)则可以进行转换
var str interface{} = "string"
// interface{} to string
fmt.Printf("%s", str.(string))
情况2: interface{} 原始数据类型非 string 类型,若通过x.(T)转换为string类型会报错,则需要通过fmt.Sprintf("%v", value)进行转换
mapValues := map[string]interface{}{
"ID": 100,
"Name": "Interface to string",
}
var arrayValues []string
for _, value := range mapValues {
// interface to string
str := fmt.Sprintf("%v", value)
arrayValues = append(arrayValues, str)
}