我是新来的(golang)。这就是为什么我的问题可能无关紧要(或无法回答)的原因。
我创建了两个结构。这两个都嵌入了另一个结构。现在我想更新函数内嵌入结构的字段。
package main
import (
"fmt"
"reflect"
"time"
)
type Model struct {
UpdatedAt time.Time
}
type Fruit struct {
Model
label string
}
type Animal struct {
Model
label string
}
func update(v interface{}) {
reflectType := reflect.TypeOf(v)
reflectKind := reflectType.Kind()
if reflectKind == reflect.Ptr {
reflectType = reflectType.Elem()
}
m := reflect.Zero(reflectType)
fmt.Println(m)
}
func main() {
apple := &Fruit{
label: "Apple",
}
tiger := &Animal{
label: "Tiger",
}
update(apple)
update(tiger)
fmt.Println(apple)
fmt.Println(tiger)
}
我希望实现
update
函数,以便它将当前时间放入传递的结构的 UpdatedAt
中。但我做不到。
在这种情况下,
Fruit
和Animal
的领域是相同的:label
。但它不会永远如此。请在提供建议时记住这一点。
任何指导将不胜感激。
如果您开始学习围棋,我会避免使用
reflect
或interface{}
。初学者通常会像 void *
拐杖一样依靠它们。尝试使用具体类型或定义明确的接口。
这应该让你去:
type Timestamper interface {
Update()
UpdatedTime() time.Time
}
type Model struct {
updated time.Time
}
func (m *Model) Update() { m.updated = time.Now() }
func (m *Model) UpdatedTime() time.Time { return m.updated }
type Fruit struct {
Model
label string
}
type Animal struct {
Model
label string
}
// update will work with a `Model` `Animal` or `Fruit`
// as they all implement the `Timestamper` interface`
func update(v Timestamper) {
v.Update()
}
假设你想通过反射来实现:首先,你必须传递一个指向结构的指针。您现在正在传递结构的副本,因此在
update
中所做的任何修改都将在副本上完成,而不是在您传入的实例上完成。然后,您可以在传入的接口中查找字段UpdatedAt
,并设置它。
也就是说,这可能不是最好的方法。另一种无需反思的方法是:
func update(in *Model) {
in.UpdatedAt = time.Now()
}
func main() {
apple := &Fruit{}
update(&apple.Model)
}
或:
func (in *Model) update() {
in.UpdatedAt = time.Now()
}
func main() {
apple := &Fruit{}
apple.update()
}