在Go中将struct放入切片的更好方法是什么

时间:2017-03-26 12:31:27

标签: go struct slice

我有func Struct2slice(somestruct Manystrings)[] string 将字符串结构转换为字符串切片。我相信有更好,更快,更简单的方法,没有导入反映。有吗?

   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
}

2 个答案:

答案 0 :(得分:2)

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

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

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

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

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)
    }
  }
}

答案 1 :(得分:1)

没有

为什么会这样?首先,你的功能只有五行代码,它已经简短了。其次,将结构转换为字符串切片不是正常的&#34;要做的事情,至少不足以让它比现在更容易。就目前而言,它只比Javascript或PHP稍微不方便一点,对于强类型编译语言而言,这已经是一项相当大的成就。