作为接口传递的函数内部的Golang更新结构字段

问题描述 投票:0回答:2

我是新来的(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中。但是我无法做到这一点。

在这种情况下,FruitAnimal的字段相同:label。但并非总是如此。提供建议时请记住这一点。

任何指导将不胜感激。

go struct reflection interface embedding
2个回答
1
投票

假设您想通过反射来实现:首先,您必须将指针传递给该结构。现在,您正在传递该结构的副本,因此在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()
}

0
投票

如果您开始学习go,我会避免reflectinterface{}。初学者通常像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
}

func update(v Timestamper) {
    v.Update()
}

操场:https://play.golang.org/p/wDCq-MO-J38

© www.soinside.com 2019 - 2024. All rights reserved.