go - 将未知长度的 slice 中的值分配给 Go 中的结构体?

标签 go struct slice

我从github上的一些有用的包中找到了下面的案例,它看起来是如此丑陋和愚蠢。我认为更好的代码设计可以避免这种情况,但是如果遇到这种情况,是不是可以写得更简洁呢?

有没有更好的方法来代替连续检查 slice 长度?

package main

type NumberSet struct {
    SetName string
    Number1 int
    Number2 int
    Number3 int
}

func main() {
    set := &NumberSet{SetName: "test"}
    var numbers []int
    // assume that we don't know the actual length of slice
    numbers = append(numbers, 1)
    numbers = append(numbers, 2)

    length := len(numbers)
    if length > 0 {
        set.Number1 = numbers[0]
    }
    if length > 1 {
        set.Number2 = numbers[1]
    }
    if length > 2 {
        set.Number3 = numbers[2]
    }
}

最佳答案

您可以使用for range来范围化数字,这样您就可以省略长度检查,并使用switch进行字段分配,例如:

for i, v := range numbers {
    switch i {
    case 0:
        set.Number1 = v
    case 1:
        set.Number2 = v
    case 2:
        set.Number3 = v
    }
}

Go Playground 上尝试一下.

您还可以列出另一个 slice 中的字段地址,并使用单个循环来进行分配:

ps := []*int{&set.Number1, &set.Number2, &set.Number3}
for i, v := range numbers {
    *ps[i] = v
}

Go Playground 上尝试一下.

如果性能并不重要,并且分配的字段是连续的,则可以使用反射来进行分配,而无需枚举字段,例如:

rv := reflect.ValueOf(set).Elem()
for i, v := range numbers {
    rv.Field(1 + i).Set(reflect.ValueOf(v)) // 1 is the offset of Number1
}

Go Playground 上尝试一下.

关于go - 将未知长度的 slice 中的值分配给 Go 中的结构体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72853553/

相关文章:

go - 如何使用 aerospike 客户端进行“触摸获取”

arrays - Swift - 混洗过滤后的结构数组不会改变原始数组

string - 向现有结构添加更多字段名

go - 如何为 pq 驱动程序准备一个带有动态表名的 INSERT 语句

go - 在 Go 中给定多个 URL 参数的过程图像

arrays - 如何将 byte slice 段 (&[u8]) 的缓冲区转换为整数?

json - jq substr() 相当于格式化一个值

python - 带索引的 Numpy 分配

go - 如何发布一个 Go 包

c - 如何在 C 中的结构中存储可变长度数组