【问题标题】:What's the better way to put struct into slice in Go在 Go 中将 struct 放入 slice 的更好方法是什么
【发布时间】:2017-03-26 12:31:26
【问题描述】:

我有 func Struct2slice(somestruct Manystrings) []string 将字符串结构转换为字符串切片。我相信有更好、更快和更简单的方法来做到这一点,而无需 import reflect 。有吗?

   type Manystrings struct {
        string1 string
        string2 string
        string3 string
    }

func Struct2slice(somestruct Manystrings) []string {

    v := reflect.ValueOf(somestruct)
    values := make([]string, v.NumField())
    for i := 0; i < v.NumField(); i++ {
        values[i] = v.Field(i).String()
    }
    return values
}

【问题讨论】:

    标签: go struct slice


    【解决方案1】:

    可以直接构造三个字符串的切片——不需要reflect

    func (ms *ManyStrings) Strings() []string {
        return []string{ms.string1, ms.string2, ms.string3}
    }
    

    您可以为您拥有的每个结构定义这样的方法。这很简单,尽可能快,而且易于理解。

    如果您担心像这样的手动编写的方法可能与实际的结构定义不一致,我可能会在单元测试的问题中使用基于反射的解决方案来检查 @ 987654323@ 方法是正确的。像这样的:

    func toStrings(x interface{}) []string {
      v := reflect.Indirect(reflect.ValueOf(x))
      var r []string
        for i := 0; i < v.NumField(); i++ {
            r = append(r, v.Field(i).String())
        }
        return r
    }
    
    func TestStrings(t *testing.T) {
      egs := []interface{Strings()[]string}{
        &ManyStrings{"one", "two", "three"},
        &ManyStrings{},
        &ManyStrings{"a", "", ""},
        &ManyStrings{"", "b", ""},
        &ManyStrings{"", "", "c"},
        ... any other test cases
      }
      for _, ex := range egs {
        got, want := ex.Strings(), toStrings(ex)
        if !reflect.DeepEqual(got, want) {
          t.Errorf("%v.Strings() = %v, want %v", ex, got, want)
        }
      }
    }
    

    【讨论】:

    • 优秀的答案,非常感谢。对于那个TestStrings,我感到恐慌:reflect:在ptr Value上调用reflect.Value.NumField [恢复]恐慌:reflect:在ptr Value上调用reflect.Value.NumField
    • 是的,对不起 - 我使用了指针接收器 Strings() 而您的代码使用了结构。我添加了缺少的reflect.Indirect
    【解决方案2】:

    没有。

    为什么会有?首先,你的函数只有五行代码,已经很简短了。其次,将结构体转换为字符串切片并不是一件“正常”的事情,至少不足以强制要求它比现在更容易。就目前而言,它只比 Javascript 或 PHP 方便一点,这对于强类型编译语言来说已经是一个相当大的成就了。

    【讨论】:

      猜你喜欢
      • 2011-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多