从结构图中调用struct

时间:2014-11-18 11:34:29

标签: struct go

您好我正在尝试类似以下示例的内容。

我作为PHP开发人员的背景(我知道!)让我很难相处。 我已经阅读了反思法则和其他来源,但这是我的头脑。我使用的方法可能是错误的...希望有人可以指出我正确的方向。

以具体方式使用它是因为版本01或02或03来自外部参数,基于此,我需要获取适当的结构并用数据库值填充它。

package V01
type Struct1 struct{
    Field1 string
    Field2 string
}

type Struct2 struct{
    Field1 string
    Field2 string
}

package V02
type Struct1 struct{
    Field1 string
    Field2 string
    ExtraField1 string
}

type Struct2 struct{
    Field1 string
    Field2 string
    ExtraField2 string
    ExtraField3 string
}

var VStructs = map[string]map[string]interface{}{
    "01": map[string]interface{}{
        "Struct1": V01.Struct1{},
        "Struct2": V01.Struct2{},
    },
    "02": map[string]interface{}{
        "Struct1": V02.Struct1{},
        "Struct2": V02.Struct2{},
    }, 
    "03" : map[string]interface{}{
        "Struct1": V01.Struct1{},
        "Struct2": V02.Struct2{},
    }, 
}

 // I get the struct fieldnames and so on.
 fmt.Printf("%+v\n", VStructs["01"]["Struct1"] ) 

 // I cannot access any of the fields though because it is an interface
 fmt.Println( VStructs["01"]["Struct1"].Field1 ) // PANIC! 

 // Type Switching is not working either since the version can be variable.
 s := VStructs["01"]["Struct1"].Field1 
 switch x := s.(type) {
 case reflect.Struct: // PANIC! reflect.Struct (type reflect.Kind) is not a type
    fmt.Println("I am an struct")
 default:
    fmt.Println("I am an no struct")
 }

所以也许可以告诉我一个合适的方法。或者也许是一个包装函数来返回正确的结构......此时没有任何线索。

希望很清楚,如果被要求,还会详细说明。

2 个答案:

答案 0 :(得分:0)

您无法以这种方式访问​​地图内的结构,因为可能没有结构。在您的示例中,VStructs["foo"]["bar"].Field1会是什么?您无法知道它是否真的是地图中的空结构,或者没有任何内容,并且地图访问只返回了该类型的空值。你应该做的是明确的检查:

v, ok := VStructs["01"]["Struct1"]
if !ok {
    // Handle the case of the missing struct.
}
// It is also a good practice to check type assertions.
s, ok := v.(V01.Struct1)
if !ok {
    // Handle the case when v is not V01.Struct1.
}
f = s.Field1

答案 1 :(得分:0)

好的,因为这个问题可能与golang的使用方式有冲突。

我写了一个包来满足我的需求:

  

根据所选版本(在URL或标题中,无论你喜欢什么),我们检索结构图。我们现在可以选择我们需要的实际结构,设置一些值,最后将其发送回屏幕或将其发送到DB(在我的情况下为gorp)。

可以在https://github.com/donseba/contractor/

找到包裹