1 回答
TA贡献1810条经验 获得超4个赞
为了避免在评论中进行一些扩展讨论,我将回答解释我将选择的两种方法。一般来说,我会避免反射方法。在某些情况下会调用它,但大多数情况下,越冗长、字面意思、简单的代码会更好,即使它多几行并且这些方法的功能之间存在一些重叠。
所以,从简单的例子开始。假设您有 3 种类型GroceryStore,ComputerStore、 和CornerStore。在每种类型定义的任何包中,定义一些类似方法的构造函数是相当常见的(它们在技术上不是构造函数,只是封装了实例化类型并返回它但目的相同的范围方法)。所以一个例子是;
func NewComputerStore(store Store) *ComputerStore {
return &ComputerStore{
Name: store["Name"],
Location: store["Location"],
//ect
}
}
当然,上面的例子是完全不安全的。实际上,您需要使用v, ok := myMape["key"]语法,然后分配 ifok和 if not 执行任何操作(可能是分配默认值、记录错误和抛出错误的某种组合)。
现在如果你想要一个通用的方法......它通常看起来更像这样(注意这是未经测试的并且比工作示例更伪代码);
func (s *Store) ConvertToObject(obj interface{}) error {
val := reflect.ValueOf(obj)
for i := 0; i < val.NumField(); i++ {
switch v := val.Field(i).(type) {
case int64:
val.Field(i).SetInt(strconv.Atoi(s[val.Field(i).Name]))
}
}
}
所以上面代码的基本思想是这样的。您从商店地图开始。调用者知道该映射应该是什么类型。他们调用此方法并传递该类型的新实例。在方法中,我们并不真正关心类型是什么,我们关心它的字段的类型是什么。所以我迭代传入的对象上的所有字段。每个字段都通过类型开关(因为对于结构中存在的每个类型,我都需要一个字符串到 X 的转换,这个方法应该使用,或者至少一个体面的基本情况),在每种类型的情况下,您可以使用字段名称进行分配以在Store地图中查找它的值并将其从字符串转换为 X。
希望这是有道理的。如果它没有真正阐明方法,我可以跟进。请记住,上面的代码不是要运行的。此外,我已经忽略了所有错误处理,您需要大量的错误处理才能使通用函数工作(如果转换失败该怎么办?如果类型不被识别怎么办?所有其他可能不常见的错误呢?地方?)。
- 1 回答
- 0 关注
- 151 浏览
添加回答
举报