Store information/reference about structure

前端 未结 1 1565
春和景丽
春和景丽 2021-01-22 22:16

I am looking for a way to store information which struct a function should use. Each struct corresponds to certain database table.

type Record struct {
   TableN         


        
相关标签:
1条回答
  • 2021-01-22 23:14

    You may use reflect.Type to represent / describe a Go type. And at runtime, you may use reflect.New() to obtain a pointer to the zeroed value of this type wrapped in a reflect.Value. And if you need a slice instead of a single value, you may use reflect.SliceOf(), or obtain the type descriptor of the slice value in the first place.

    If you store refect.Type values of your tables, this is how you can use it:

    type Record struct {
       TableName  string
       PrimaryKey string
       XormStruct reflect.Type
    }
    
    var ListOfTables [...]Record {
       {"User", "id", reflect.TypeOf((*User)(nil)).Elem()},
       {"Post", "post_id", reflect.TypeOf((*Post)(nil)).Elem()},
    }
    
    // User is xorm struct
    type User struct {
       Id   int64
       Name string
    }
    
    // Post is xorm struct
    type Post struct {
       Post_id int64
       Name    string
       Other   string
    }
    

    Note you must use exported fields!

    And then handling the tables:

    for _, rec := range ListOfTables {
        entries := reflect.New(reflect.SliceOf(t.XormStruct)).Interface()
        err := xorm.Find(entries)
        // Handle error
    
        err := xml.Marshal(entries)
        // Handle error
    }
    

    You can see a working example (proof of concept) of this (without xorm as that is not available on the Go Playground) using JSON: Go Playground.

    If you were to store reflect.Type values of slices in the first place:

    var ListOfTables [...]Record {
       {"User", "id", reflect.TypeOf([]User{})},
       {"Post", "post_id", reflect.TypeOf([]Post{})},
    }
    

    And using it is also simpler:

    for _, rec := range ListOfTables {
        entries := reflect.New(t.XormStruct).Interface()
        err := xorm.Find(entries)
        // Handle error
    
        err := xml.Marshal(entries)
        // Handle error
    }
    

    See proof of concept of this: Go Playground.

    Note that if Record holds slice types (in the field XormStruct), should you ever need to access the type of the struct (the element type of the struct), you may use Type.Elem() for that.

    0 讨论(0)
提交回复
热议问题