我在构建一个可以动态使用参数化结构的函数时遇到了一些麻烦。出于这个原因,我的代码有 20 多个相似的函数,除了基本上使用的一种类型。我的大部分经验是使用 Java,我只是开发基本的通用函数,或者使用普通的 Object 作为函数的参数(以及从那时起的反射)。我需要类似的东西,使用 Go。我有几种类型,例如:// The List structs are mostly needed for json marshallingtype OrangeList struct { Oranges []Orange}type BananaList struct { Bananas []Banana}type Orange struct { Orange_id string Field_1 int // The fields are different for different types, I am simplifying the code example}type Banana struct { Banana_id string Field_1 int // The fields are different for different types, I am simplifying the code example}然后我有功能,基本上每个列表类型:// In the end there are 20+ of these, the only difference is basically in two types! // This is very un-DRY!func buildOranges(rows *sqlx.Rows) ([]byte, error) { oranges := OrangeList{} // This type changes for rows.Next() { orange := Orange{} // This type changes err := rows.StructScan(&orange) // This can handle each case already, could also use reflect myself too checkError(err, "rows.Scan") oranges.Oranges = append(oranges.Oranges,orange) } checkError(rows.Err(), "rows.Err") jsontext, err := json.Marshal(oranges) return jsontext, err}是的,我可以更改 sql 库以使用更智能的 ORM 或框架,但这不是重点。我想学习如何构建可以为所有不同类型处理类似功能的通用函数。我走了这么远,但它仍然无法正常工作(我认为目标不是预期的结构):func buildWhatever(rows *sqlx.Rows, tgt interface{}) ([]byte, error) { tgtValueOf := reflect.ValueOf(tgt) tgtType := tgtValueOf.Type() targets := reflect.SliceOf(tgtValueOf.Type()) for rows.Next() { target := reflect.New(tgtType) err := rows.StructScan(&target) // At this stage target still isn't 1:1 smilar struct so the StructScan fails... It's some perverted "Value" object instead. Meh. // Removed appending to the list because the solutions for that would be similar checkError(err, "rows.Scan") } checkError(rows.Err(), "rows.Err") jsontext, err := json.Marshal(targets) return jsontext, err}所以嗯,我需要提供列表类型和普通类型作为参数,然后构建其中的一个,我的其余逻辑可能很容易修复。
1 回答
- 1 回答
- 0 关注
- 163 浏览
添加回答
举报
0/150
提交
取消