假设我有两种类似的类型:
type type1 []struct {
Field1 string
Field2 int
}
type type2 []struct {
Field1 string
Field2 int
}
Run Code Online (Sandbox Code Playgroud)
是否有直接的方法将值从type1写入type2,知道它们具有相同的字段?(除了编写一个循环,将所有字段从源复制到目标)
谢谢.
nem*_*emo 50
要提供OneOfOne答案的参考,请参阅规范的" 转换"部分.
它说明了这一点
在任何这些情况下,非常量值
x都可以转换为类型T:
x可分配给T.x的类型和T底层类型相同.x的类型和T是未命名的指针类型,它们的指针基类型具有相同的基础类型.x的类型,T都是整数或浮点类型.x的类型,T都是复杂的类型.x是一个整数或一个字节或符文切片,T是一个字符串类型.x是一个字符串,T是一个字节或符文的片段.
第一个和突出显示的案例是你的情况.两种类型都有底层类型
[]struct { Field1 string Field2 int }
Run Code Online (Sandbox Code Playgroud)
基础类型定义为
如果
T是预先声明的布尔,数字或字符串类型之一或类型文字,则相应的基础类型T本身.否则,T底层类型是T其类型声明中引用的类型的基础类型.(规格,类型)
您正在使用类型文字来定义类型,因此此类型文字是您的基础类型.
One*_*One 38
对于您的具体示例,您可以轻松转换它playground:
t1 := type1{{"A", 1}, {"B", 2}}
t2 := type2(t1)
fmt.Println(t2)
Run Code Online (Sandbox Code Playgroud)
小智 14
从Go 1.8开始,将值从一种结构类型转换为另一种结构类型时,将忽略结构标记.在Go版本中,类型type1和type2将是可转换的,无论它们的struct标记如何.https://beta.golang.org/doc/go1.8#language
m.k*_*ski 11
尼古拉斯,在你后来的评论中,你说你在结构上使用了字段标签; 这些都算作定义的一部分,所以下面定义的t1和t2是不同的,你不能转换t2(t1):
type t1 struct {
Field1 string
}
type t2 struct {
Field1 string `json:"field_1"`
}
Run Code Online (Sandbox Code Playgroud)
Moh*_*h M 10
这不是标准方法,但是如果您希望有一种灵活的方法将结构转换为映射,或者如果您想在不使用 `json:"-" 的情况下删除结构的某些属性,您可以使用JSON marshal。
具体来说,我是这样做的:
type originalStruct []struct {
Field1 string
Field2 int
}
targetStruct := make(map[string]interface{}) // `targetStruct` can be anything of your choice
temporaryVariable, _ := json.Marshal(originalStruct)
err = json.Unmarshal(temporaryVariable, &targetStruct)
if err != nil {
// Catch the exception to handle it as per your need
}
Run Code Online (Sandbox Code Playgroud)
可能看起来像一个黑客,但在我的大多数任务中非常有用。
小智 7
对于已经支持泛型的 go v1.18,基本上我只是创建接受任何类型参数的方法,并使用 json.Marshal / Unmarshal 将其转换为另一种类型
// utils.TypeConverter
func TypeConverter[R any](data any) (*R, error) {
var result R
b, err := json.Marshal(&data)
if err != nil {
return nil, err
}
err = json.Unmarshal(b, &result)
if err != nil {
return nil, err
}
return &result, err
}
Run Code Online (Sandbox Code Playgroud)
假设我有一个名为 models.CreateUserRequest 的结构,我想将其转换为 models.User。注意json标签必须相同
// models.CreateUserRequest
type CreateUserRequest struct {
Fullname string `json:"name,omitempty"`
RegisterEmail string `json:"email,omitempty"`
}
// models.User
type User struct {
Name string `json:"name,omitempty"`
Email string `json:"email,omitempty"`
Phone string `json:"phone,omitempty"`
}
Run Code Online (Sandbox Code Playgroud)
我可以像这样使用上面的 utils 方法
user := models.CreateUserRequest {
Name: "John Doe",
Email: "johndoe@gmail.com"
}
data, err := utils.TypeConverter[models.User](&user)
if err != nil {
log.Println(err.Error())
}
log.Println(reflrect.TypeOf(data)) // will output *models.User
log.Println(data)
Run Code Online (Sandbox Code Playgroud)
您可以手动使用映射器函数将类型 t1 的每个元素映射到类型 t2。它会起作用的。
func GetT2FromT1(ob1 *t1) *t2 {
ob2 := &t2 { Field1: t1.Field1, }
return ob2
}
Run Code Online (Sandbox Code Playgroud)