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

在Go中将结构放入切片的更好方法是什么,go,struct,slice,Go,Struct,Slice,我使用func Struct2slicesomestruct Manystrings[]字符串将字符串结构转换为字符串片段。我相信有更好、更快、更简单的方法可以做到这一点,而无需考虑。有吗 type Manystrings struct { string1 string string2 string string3 string } func Struct2slice(somestruct Manystrings) []string

我使用func Struct2slicesomestruct Manystrings[]字符串将字符串结构转换为字符串片段。我相信有更好、更快、更简单的方法可以做到这一点,而无需考虑。有吗

   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
}
没有


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

一个人可以直接构造三个字符串的片段-不需要反射

可以为每个结构定义这样的方法。这很简单,尽可能快,也很容易理解

如果您担心像这样的手工编写的方法如何与实际的结构定义不一致,我可能会使用单元测试问题中基于反射的解决方案来检查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)
    }
  }
}

回答得很好,非常感谢。对于这个TestStrings,我得到了panic:reflect:call of reflect.Value.NumField on ptr Value[recovered]panic:reflect:call of reflect.Value.NumField on ptr Value耶,对不起-我使用了字符串指针接收器,而您的代码使用了结构。我添加了缺少的反射。间接。
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)
    }
  }
}