gconv
模块通过Struct
转换方法执行struct
类型转换,其定义如下:
其中:
params
为需要转换到struct
的变量参数,可以为任意数据类型,常见的数据类型为map
。pointer
为需要执行转的目标struct
对象,这个参数必须为该struct
的对象指针,转换成功后该对象的属性将会更新。mapping
为自定义的map键名
到strcut属性
之间的映射关系,此时params
参数必须为map
类型,否则该参数无意义。大部分场景下使用可以不用提供该参数,直接使用默认的转换规则即可。
更多的struct
相关转换方法请参考接口文档:
转换规则
struct
中需要匹配的属性必须为 公开属性 (首字母大写)。- 根据
params
类型的不同,逻辑会有不同:params
参数类型为map
:键名会自动按照 不区分大小写 且 忽略特殊字符 的形式与struct属性进行匹配。params
参数为其他类型:将会把该变量值与struct
的第一个属性进行匹配。- 此外,如果
struct
的属性为复杂数据类型如slice
,map
,strcut
那么会进行递归匹配赋值。
- 如果匹配成功,那么将键值赋值给属性,如果无法匹配,那么忽略该键值。
以下是几个map
键名与struct
属性名称的示例:
map键名 struct属性 是否匹配
name Name match
Email Email match
nickname NickName match
NICKNAME NickName match
Nick-Name NickName match
nick_name NickName match
nick name NickName match
NickName Nick_Name match
Nick-name Nick_Name match
nick_name Nick_Name match
nick name Nick_Name match
自动创建对象
当给定的pointer
参数类型为**struct
时,Struct
方法内部将会自动创建该struct
对象,并修改传递变量指向的指针地址。
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
func main() {
type User struct {
Uid int
}
params := g.Map{
"uid": 1,
"name": "john",
}
var user *User
if err := gconv.Struct(params, &user); err != nil {
panic(err)
}
g.Dump(user)
}
执行后,输出结果为:
Struct
递归转换
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
func main() {
type Ids struct {
Id int `json:"id"`
Uid int `json:"uid"`
}
type Base struct {
Ids
CreateTime string `json:"create_time"`
}
type User struct {
Base
Passport string `json:"passport"`
Password string `json:"password"`
Nickname string `json:"nickname"`
}
data := g.Map{
"id" : 1,
"uid" : 100,
"passport" : "john",
"password" : "123456",
"nickname" : "John",
"create_time" : "2019",
}
user := new(User)
gconv.Struct(data, user)
g.Dump(user)
}
执行后,终端输出结果为:
{
"Base": {
"id": 1,
"uid": 100,
"create_time": "2019"
},
"nickname": "John",
"passport": "john",
"password": "123456"
}
示例1,基本使用
可以看到,我们可以直接通过Struct
方法将map
按照默认规则绑定到上,也可以使用struct tag
的方式进行灵活的设置。此外,Struct
方法有第三个map
参数,用于指定自定义的参数名称到属性名称的映射关系。
执行后,输出结果为:
{
"Uid": 1,
"Name": "john",
"SiteUrl": "https://goframe.org",
"NickName": "johng",
"Pass1": "123",
}
{
"Uid": 2,
"Name": "smith",
"SiteUrl": "https://goframe.org",
"NickName": "johng",
"Pass1": "111",
"Pass2": "222"
}
示例2,复杂属性类型
package main
import (
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/frame/g"
"fmt"
)
func main() {
type Score struct {
Name string
Result int
}
type User1 struct {
Scores Score
}
type User2 struct {
Scores *Score
}
user1 := new(User1)
user2 := new(User2)
scores := g.Map{
"Scores": g.Map{
"Name": "john",
"Result": 100,
},
}
if err := gconv.Struct(scores, user1); err != nil {
fmt.Println(err)
} else {
g.Dump(user1)
}
if err := gconv.Struct(scores, user2); err != nil {
fmt.Println(err)
} else {
g.Dump(user2)
执行后,输出结果为: