0

目前,我正在使用一组结构,这些结构定义了文档的多个版本。大多数字段在这些不同版本之间共享,实际差异非常微妙。我想要做的是重构解析这个文档的代码。为此,如果我可以概括一些属性,那将非常好,我不需要确切知道我正在工作的类型,就知道该类型将具有特定字段。

我曾考虑过使用反射,但如果我能避免它,我会的。

假设我们有:

type v1 struct{
  a int
}

type v2 struct{
 a int
 b string
}

我想做的是

func main(){
 var v1 v1
 var v2 v2

 foo(v1)
 foo(v2)
}


func foo (root interface{}){
  root.a = x
}

可能吗?还是有其他方法?

编辑:1 - 这不是“从界面获取所有字段”的副本,因为我的问题不是要弄清楚我正在处理什么类型,而是以相同的方式操作/处理不同的类型。2 - 这可能是“如何编写一个函数来处理golang中的两种类型的输入数据”的副本,但提供的答案无法解决我的问题。

4

1 回答 1

0

使用匿名字段、方法和接口。您可以定义一个新结构,其中包含所有其他结构的所有公共属性。然后,可以在这个共享结构上定义一个接口,列出处理公共属性的所有方法。最后,在之前的结构中,您只需要用这个新接口替换所有公共字段。此时,您可以编写将接口作为输入并通过公开方法处理内部公共字段的通用函数。

type SettableA interface{
    SetA(int)
    A() int
}

type sharedA struct {
    a int
}

func (s *sharedA) SetA(val int) {
    s.a = val
}

func (s *sharedA) A() int {
    return s.a
}

type v1 struct {
    SettableA 
}

type v2 struct {
    SettableA 
    b string
}

func foo(root SettableA) {
    root.SetA(5)
}

func main() {
    v1var := v1{
        SettableA: &sharedA{},
    }
    foo(v1var)
    v2var := v2{
        SettableA: &sharedA{},
        b: "test",
    }
    foo(v2var)
    fmt.Printf("V1: %v\nV2: %v\n", v1var.A(), v2var.A())
}

这里的接口不是绝对必要的,但它允许您编写一个处理不同具体类型的通用函数。

https://play.golang.org/p/BgxYrbGE426

于 2019-07-03T23:09:22.613 回答