英文:
How to modify object and struct from an existing struct?
问题
我有一个结构体,如下所示:
type person struct{
name string
phone string
address string
}
我想将其转换为以下形式(修改phone和address)我只有对象,没有结构体。
type person2 struct {
name string
phone []struct {
value string
}
address []struct {
value string
}
}
我应该如何基于已有的结构体创建新的结构体?我只想转换选定的字段。
我查看了反射(reflection),但不知道从何开始/如何使用它。
英文:
I have a struct say
type person struct{
name string
phone string
address string
}
and I want to transform it to this (modify phone and address) I only have the object not the struct.
type person2 struct {
name string
phone []struct {
value string
}
address []struct {
value string
}
}
How can I create new struct based on one I have ? I want to transform selected fields only.
I looked into reflection but don't know where to start/how to use it.
答案1
得分: 4
**前言:**如果你只有person
类型而没有person2
类型,你需要先编写person2
。Go是一种静态类型语言,你不能在运行时创建person2
。你可以手动编写person2
,或者使用go generate
通过编写生成器代码来生成,但这并不会更简单。
你也可以使用类似map[string]interface{}
的方式来模拟动态结构,但这既不友好也不快速。更不用说你还必须使用类型断言,因为值类型是interface{}
...
要从person
的值创建一个person2
的值,你不需要使用反射,可以简单地手动编码:
func transform(p person) person2 {
return person2{
p.name,
[]struct{ value string }{{p.phone}},
[]struct{ value string }{{p.address}},
}
}
请注意,这看起来有点奇怪,因为你在person2.phone
和person2.address
中使用了匿名结构的切片,并且为了使用复合字面量初始化匿名结构,必须重复匿名结构的定义。
测试一下:
p := person{"Bob", "1234", "New York"}
fmt.Println(p)
p2 := transform(p)
fmt.Println(p2)
输出结果(在Go Playground上尝试):
{Bob 1234 New York}
{Bob [{1234}] [{New York}]}
注意:
注意,你的person2
过于复杂了。它可以简化为这样:
type person2 struct {
name string
phones []string
addresses []string
}
然后,转换可以变成一行代码:
func transform(p person) person2 {
return person2{p.name, []string{p.phone}, []string{p.address}}
}
输出结果(在Go Playground上尝试):
{Bob 1234 New York}
{Bob [1234] [New York]}
英文:
Foreword: if you only have the type person
and not person2
, you have to first write person2
. Go is statically typed language, you can't just create person2
at runtime. You may write person2
manually or use go generate
by writing the generator code yourself, but it won't be any simpler.
You could also use something like map[string]interface{}
to mimic a dynamic struct, but that won't be any friendlier nor faster. Not to mention you'd have to use type assertions as value type is interface{}
...
To create a value of person2
from a value of person
, you don't need reflection, you can simply manually code it:
func transform(p person) person2 {
return person2{
p.name,
[]struct{ value string }{{p.phone}},
[]struct{ value string }{{p.address}},
}
}
Note that this may look a little weird, and that's because you used a slice of anonymous struct for person2.phone
and person2.address
, and to initialize an anonymous struct with a composite literal, the anonymous struct definition has to be repeated.
Testing it:
p := person{"Bob", "1234", "New York"}
fmt.Println(p)
p2 := transform(p)
fmt.Println(p2)
Output (try it on the Go Playground):
{Bob 1234 New York}
{Bob [{1234}] [{New York}]}
Note:
Note that your person2
is unnecessarily complex. It could be as simple as this:
type person2 struct {
name string
phones []string
addresses []string
}
And then the transformation is a one-liner:
func transform(p person) person2 {
return person2{p.name, []string{p.phone}, []string{p.address}}
}
Output (try it on the Go Playground):
{Bob 1234 New York}
{Bob [1234] [New York]}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论