英文:
What's the best practice to infer the methods?
问题
我有一个自定义的时间格式,用于正确编码/解码 JSON。然而,每当我需要进行时间计算时,我都需要进行类型转换。这样做是否正确?保持进行类型转换感觉有点丑陋。例如,当我需要“更新”值时,我需要进行两次类型转换(一次转换为时间类型,一次转换为我的类型)。
type Mytime time.Time
var t Mytime
t = Mytime(time.Now())
// 将一个小时添加到我的自定义时间
t = Mytime(time.Time(t).Add(1 * time.Hour))
英文:
I have a custom time format which I use to properly encode/decode json. However whenever I need to do a time computation I need to do a cast. Is this the right way? It feels a bit ugly to keep casting. For example when I need to "update" the value I need to cast it twice ( once to time and once to my type)
type Mytime time.Time
var t Mytime
t = Mytime(time.Now())
// Add an hour to my typed time
t = Mytime(time.Time(t).Add(1 * time.Hour))
答案1
得分: 3
你可以使用嵌入来扩展time.Time
类型,例如:
type MyTime struct {
time.Time
}
然后你可以定义MarshalJSON
方法:
func (t MyTime) MarshalJSON() ([]byte, error) {
// 实现你的逻辑
}
并且仍然可以访问所有time.Time
的方法。例如:
t := MyTime{time.Now()}
t.Time = t.Add(time.Hour)
完整示例展示了嵌入和非嵌入自定义时间类型之间的区别。请注意,嵌入仍然不能与期望time.Time
值的其他组件透明地进行交互。(这里省略了创建这些类型的原因,例如添加MarshalJSON
方法)。
package main
import (
"fmt"
"time"
)
type YourTime time.Time
type MyTime struct{ time.Time }
// 一些随机函数,可能在第三方包中,处理time.Time值。
func fn(t time.Time) {
fmt.Println("fn got:", t)
}
func fn2() time.Time {
return time.Unix(14e8, 0)
}
func main() {
var t1 = YourTime(time.Now())
//t1 = t1.Add(time.Hour) // 编译错误
t1 = YourTime(time.Time(t1).Add(time.Hour))
fmt.Println("ugly t1:", t1)
fmt.Println("nice t1:", time.Time(t1))
//fn(t1) // 编译错误
fn(time.Time(t1))
//t1 = fn2() // 编译错误
t1 = YourTime(fn2())
var t2 = MyTime{time.Now()}
// t2 = t2.Add(time.Hour) // 编译错误
t2.Time = t2.Add(time.Hour)
fmt.Println("t2:", t2)
//fn(t2) // 编译错误
fn(t2.Time)
//t2 = fn2() // 编译错误
t2.Time = fn2()
}
输出:
ugly t1: {63393494400 0 0x1c9340}
nice t1: 2009-11-11 00:00:00 +0000 UTC
fn got: 2009-11-11 00:00:00 +0000 UTC
t2: 2009-11-10 23:00:00 +0000 UTC
fn got: 2009-11-10 23:00:00 +0000 UTC
你可以在Playground上运行这个示例。
英文:
Presumably you have type Mytime time.Time
. If instead you embedded it:
type MyTime struct {
time.Time
}
Then you could have:
func (t MyTime) MarshalJSON() ([]byte, error) {
… whatever …
}
and still access all of time.Time
's methods.
E.g. something like:
t := MyType{time.Now()}
t.Time = t.Add(time.Hour)
Fuller example showing differences between embedded and non-embedded custom time types. Note that embedding still doesn't allow for transparent inter-use with things that expect a time.Time
value. (The reason for making these types, e.g. to add a MarshalJSON
method has been omitted here).
package main
import (
"fmt"
"time"
)
type YourTime time.Time
type MyTime struct{ time.Time }
// Some random functions, perhaps in a third party package,
// that deals with time.Time values.
func fn(t time.Time) {
fmt.Println("fn got:", t)
}
func fn2() time.Time {
return time.Unix(14e8, 0)
}
func main() {
var t1 = YourTime(time.Now())
//t1 = t1.Add(time.Hour) // compiler error
t1 = YourTime(time.Time(t1).Add(time.Hour))
fmt.Println("ugly t1:", t1)
fmt.Println("nice t1:", time.Time(t1))
//fn(t1) // compiler error
fn(time.Time(t1))
//t1 = fn2() // compiler error
t1 = YourTime(fn2())
var t2 = MyTime{time.Now()}
// t2 = t2.Add(time.Hour) // compiler error
t2.Time = t2.Add(time.Hour)
fmt.Println("t2:", t2)
//fn(t2) // compiler error
fn(t2.Time)
//t2 = fn2() // compiler error
t2.Time = fn2()
}
Output:
ugly t1: {63393494400 0 0x1c9340}
nice t1: 2009-11-11 00:00:00 +0000 UTC
fn got: 2009-11-11 00:00:00 +0000 UTC
t2: 2009-11-10 23:00:00 +0000 UTC
fn got: 2009-11-10 23:00:00 +0000 UTC
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论