go - 动态地一起添加值

标签 go

我正在尝试创建一个查看结构元数据的服务,并确定要将哪些字段加在一起。这是一个示例 Struct 和我一直在 Go Playground 中使用的函数,用于将东西加在一起。这只是一个示例结构,显然并非所有字段都是递增的。

出现“ panic :接口(interface)转换:接口(interface)是 int,而不是 int64”时出现 panic ,我该如何以正确的方式执行此操作?

package main

import (
   "fmt"
   "reflect"
   "strconv"
)

type TestResult struct {
    Complete         int        `json:"complete" increment:"true"`
    Duration         int        `json:"duration" increment:"true"`
    Failed           int        `json:"failed" increment:"true"`
    Mistakes         int        `json:"mistakes" increment:"true"`
    Points           int        `json:"points" increment:"true"`
    Questions        int        `json:"questions" increment:"true"`
    Removal_duration int        `json:"removal_duration" increment:"true"`
}

func main() {
    old := TestResult{}
    new := TestResult{}

    old.Complete = 5
    new.Complete = 10

    values := reflect.ValueOf(old)
    new_values := reflect.ValueOf(new)
    value_type := reflect.TypeOf(old)
    fmt.Println(values)
    fmt.Println(new_values)

    for i := 0; i < values.NumField(); i++ {
       field := value_type.Field(i)
       if increment, err := strconv.ParseBool(field.Tag.Get("increment")); err == nil && increment {
          reflect.ValueOf(&new).Elem().Field(i).SetInt(new_values.Field(i).Interface().(int64) + values.Field(i).Interface().(int64))
       }
    }
    fmt.Println(new)
}

Playground :https://play.golang.org/p/QghY01QY13

最佳答案

因为字段的类型是int,所以您必须键入assert to int

reflect.ValueOf(&new).Elem().Field(i).SetInt(int64(new_values.Field(i).Interface().(int) + values.Field(i).Interface().(int)))

playground example

另一种方法是使用 Int()而不是 Interface().(int)。这种方法适用于所有有符号整数类型:

reflect.ValueOf(&new).Elem().Field(i).SetInt(new_values.Field(i).Int() + values.Field(i).Int())

playground example

以下是对所有数字类型执行此操作的方法:

        v := reflect.ValueOf(&new).Elem().Field(i)
        switch v.Kind() {
        case reflect.Int,
            reflect.Int8,
            reflect.Int16,
            reflect.Int32,
            reflect.Int64:
            v.SetInt(new_values.Field(i).Int() + values.Field(i).Int())
        case reflect.Uint,
            reflect.Uint8,
            reflect.Uint16,
            reflect.Uint32,
            reflect.Uint64:
            v.SetUint(new_values.Field(i).Uint() + values.Field(i).Uint())
        case reflect.Float32, reflect.Float64:
            v.SetFloat(new_values.Field(i).Float() + values.Field(i).Float())
        }

playground example

关于go - 动态地一起添加值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35213411/

相关文章:

go: 找不到 GOROOT 目录: C:\Go; C:\Go\bin

go - 为什么一些 golang.org 包以 `x` 为前缀

performance - 根据前一个 slice 创建一个新 slice ,没有给定值

sql-server - 戈兰 : "Err TLS Handshake failed: tls: server selected unsupported protocol version 301" when trying to connect to sql server (diferent host)

go - 使用 Go Web 语言提供静态内容

go - 如何在 Go 中保持 "package"状态?

golang代码插入/替换

go - 命令需要换行才能完成

c - 将具有 union 字段的 C 结构映射到 Go 结构

golang 无法解析 json 项