我是一名经验丰富的 Python 程序员,但我对 Golang 还是个新手,所以如果这是一个明显或愚蠢的问题,我深表歉意。但是我正在尝试创建我自己的类型,我希望它的行为与基类型完全相同,但有几个方法被覆盖。原因是因为我使用的几个库正在检查类型time.Time,我希望它匹配。
type PythonTime struct {
time.Time
}
var pythonTimeFormatStr = "2006-01-02 15:04:05-0700"
func (self *PythonTime) UnmarshalJSON(b []byte) (err error) {
// removes prepending/trailing " in the string
if b[0] == '"' && b[len(b)-1] == '"' {
b = b[1 : len(b)-1]
}
self.Time, err = time.Parse(pythonTimeFormatStr, string(b))
return
}
func (self *PythonTime) MarshalJSON() ([]byte, error) {
return []byte(self.Time.Format(pythonTimeFormatStr)), nil
}
type OtherType struct {
Uuid string `json:"uuid`
Second PythonTime `json:"second"`
Location string `json:"location"`
Action string `json:"action"`
Duration int `json:"duration"`
Value string `json:"value"`
}
因此,上述内容适用于编组和解组 JSON。但是,对于我正在使用的库(gocql 和 cqlr),他们正在检查类型是否为time.Time类型,以便他们可以在将其放入 C* 之前进行一些其他修改。我如何让我的PythonTime类型等同于显示time.Time 或覆盖对象的默认编组/解组,time.Time只是为了使用我的OtherType对象?
我的临时解决方案是修改他们的代码,并为与PythonTime类型做同样事情的time.Time类型添加一个特例。但是,这导致我循环导入并且不是最佳解决方案。这是我修改后的代码。
func marshalTimestamp(info TypeInfo, value interface{}) ([]byte, error) {
switch v := value.(type) {
case Marshaler:
return v.MarshalCQL(info)
case int64:
return encBigInt(v), nil
case time.Time:
if v.IsZero() {
return []byte{}, nil
}
x := int64(v.UTC().Unix()*1e3) + int64(v.UTC().Nanosecond()/1e6)
return encBigInt(x), nil
case models.PythonTime:
x := int64(v.UTC().Unix()*1e3) + int64(v.UTC().Nanosecond()/1e6)
return encBigInt(x), nil
}
if value == nil {
return nil, nil
}
rv := reflect.ValueOf(value)
switch rv.Type().Kind() {
case reflect.Int64:
return encBigInt(rv.Int()), nil
}
return nil, marshalErrorf("can not marshal %T into %s", value, info)
}
扬帆大鱼
素胚勾勒不出你
Smart猫小萌
相关分类