Reflection 反射-还原时间.time实例

Reflection 反射-还原时间.time实例,reflection,go,Reflection,Go,我正在go中开发一个程序,需要使用Gorilla toolkit的sessions包存储和检索一组自定义结构实例。为了恢复自定义结构,我需要使用反射特性。问题是,我名为Timestamp的结构包含两个time.time实例,我无法还原这些实例。因此,我的问题是如何恢复time.time实例 下面您可以看到我的Timespan结构的代码,以及用于存储和读取会话存储中Timespan数组的代码 type Timespan struct { ID uint8; StartDate ti

我正在go中开发一个程序,需要使用Gorilla toolkit的
sessions
包存储和检索一组自定义结构实例。为了恢复自定义结构,我需要使用反射特性。问题是,我名为
Timestamp
的结构包含两个
time.time
实例,我无法还原这些实例。因此,我的问题是如何恢复
time.time
实例

下面您可以看到我的
Timespan
结构的代码,以及用于存储和读取会话存储中
Timespan
数组的代码

type Timespan struct {
    ID uint8;
    StartDate time.Time;
    EndDate time.Time;
}

func (server *WebServer) setTimespans(writer http.ResponseWriter, request *http.Request, timespans [model.TimespanCount]*model.Timespan) error {
    var session *sessions.Session;
    var sessionDecodingException error;
    session, sessionDecodingException = server.SessionStore.Get(request, authenticationSessionName);
    if sessionDecodingException != nil {
        return sessionDecodingException;
    }


    session.Values[sessionTimestamps] = timespans;
    return nil;
}

func (server *WebServer) getTimespans(request *http.Request) ([model.TimespanCount]*model.Timespan, error) {
    var session *sessions.Session;
    var sessionDecodingException error;
    session, sessionDecodingException = server.SessionStore.Get(request, authenticationSessionName);
    var readTimespans [model.TimespanCount]*model.Timespan;
    if sessionDecodingException != nil {
        return readTimespans, sessionDecodingException;
    }

    interfaceValue := reflect.ValueOf(session.Values[sessionTimestamps]);
    var actuallyAddedTimespan *model.Timespan;
    for counter := 0; counter < model.TimespanCount; counter++ {
        actuallyAddedTimespan = &model.Timespan{};
        actuallyReflectedTimespan := interfaceValue.Index(counter).Elem();
        actuallyAddedTimespan.ID = uint8(actuallyReflectedTimespan.FieldByName("ID").Uint());
        //actuallyAddedTimespan.StartDate = actuallyReflectedTimespan.FieldByName("StartDate");
        //actuallyAddedTimespan.EndDate = actuallyReflectedTimespan.FieldByName("EndDate");
        fmt.Println(actuallyAddedTimespan);
    }
    return readTimespans, nil;
}
类型Timespan结构{
ID uint8;
开始时间。时间;
结束日期时间;
}
func(服务器*WebServer)设置时间跨度(写入程序http.ResponseWriter,请求*http.request,时间跨度[model.TimespanCount]*model.Timespan)错误{
var session*sessions.session;
var sessionDecodingException错误;
session,sessionDecodingException=server.SessionStore.Get(请求,authenticationSessionName);
如果SessionCodeingException!=无{
返回sessionDecodingException;
}
session.Values[sessionTimestamps]=时间跨度;
返回零;
}
func(server*WebServer)getTimespans(request*http.request)([model.TimespanCount]*model.Timespan,错误){
var session*sessions.session;
var sessionDecodingException错误;
session,sessionDecodingException=server.SessionStore.Get(请求,authenticationSessionName);
var readTimespans[model.TimespanCount]*model.Timespan;
如果SessionCodeingException!=无{
返回readTimespans,sessionDecodingException;
}
interfaceValue:=reflect.ValueOf(session.Values[sessionTimestamps]);
var实际添加的时间跨度*model.Timespan;
对于计数器:=0;计数器
您需要获得该字段的界面:

actuallyAddedTimespan.StartDate = actuallyReflectedTimespan.FieldByName("StartDate").Interface().(time.Time)

个人意见时间,对此使用反思而不是使用简单的界面是:

  • 慢点
  • 低效
  • 如果更改结构的外观并忘记更新反射代码,可能会很容易中断
  • 使用接口的示例:

    func main() {
        ts := &Timespan{ID: 102, StartDate: time.Now().AddDate(6, 0, 0), EndDate: time.Now().AddDate(8, 0, 0)}
        m := map[string]interface{}{
            "key": ts,
        }
        switch v := m["key"].(type) {
        case Timespaner:
            fmt.Println(v.Value())
        default:
            fmt.Println("wtfmate?")
        }
    }
    
    func (ts *Timespan) Value() (id uint8, start, end time.Time) {
        return ts.ID, ts.StartDate, ts.EndDate
    }
    
    type Timespaner interface {
        Value() (id uint8, start, end time.Time)
    }
    

    您可以使用
    接口()
    函数从结构中获取
    接口{}
    值。然后,您可以使用类型断言返回正确的类型:

    func main() {
        t := &Timespan{42, time.Now(), time.Now()}
        reflectedPointer := reflect.ValueOf(t)
        reflectedTimespan := reflectedPointer.Elem()
        var timespan Timespan = reflectedTimespan.Interface().(Timespan)
        fmt.Println(*t)
        fmt.Println(timespan)
    }
    

    我不想再像Java那样编写代码了。非常感谢。然而,我并不真正理解您使用简单界面而不是反射的意思。如果您能对此稍作解释,我将不胜感激。@Lukas我添加了一个接口示例,这只是为了给您一个大致的想法,一般情况下应该避免反射,除了JSON/XML封送/解封。感谢您提供接口示例。