推断方法的最佳实践是什么?

huangapple go评论116阅读模式
英文:

What's the best practice to infer the methods?

问题

我有一个自定义的时间格式,用于正确编码/解码 JSON。然而,每当我需要进行时间计算时,我都需要进行类型转换。这样做是否正确?保持进行类型转换感觉有点丑陋。例如,当我需要“更新”值时,我需要进行两次类型转换(一次转换为时间类型,一次转换为我的类型)。

  1. type Mytime time.Time
  2. var t Mytime
  3. t = Mytime(time.Now())
  4. // 将一个小时添加到我的自定义时间
  5. 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)

  1. type Mytime time.Time
  2. var t Mytime
  3. t = Mytime(time.Now())
  4. // Add an hour to my typed time
  5. t = Mytime(time.Time(t).Add(1 * time.Hour))

答案1

得分: 3

你可以使用嵌入来扩展time.Time类型,例如:

  1. type MyTime struct {
  2. time.Time
  3. }

然后你可以定义MarshalJSON方法:

  1. func (t MyTime) MarshalJSON() ([]byte, error) {
  2. // 实现你的逻辑
  3. }

并且仍然可以访问所有time.Time的方法。例如:

  1. t := MyTime{time.Now()}
  2. t.Time = t.Add(time.Hour)

完整示例展示了嵌入和非嵌入自定义时间类型之间的区别。请注意,嵌入仍然不能与期望time.Time值的其他组件透明地进行交互。(这里省略了创建这些类型的原因,例如添加MarshalJSON方法)。

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. type YourTime time.Time
  7. type MyTime struct{ time.Time }
  8. // 一些随机函数,可能在第三方包中,处理time.Time值。
  9. func fn(t time.Time) {
  10. fmt.Println("fn got:", t)
  11. }
  12. func fn2() time.Time {
  13. return time.Unix(14e8, 0)
  14. }
  15. func main() {
  16. var t1 = YourTime(time.Now())
  17. //t1 = t1.Add(time.Hour) // 编译错误
  18. t1 = YourTime(time.Time(t1).Add(time.Hour))
  19. fmt.Println("ugly t1:", t1)
  20. fmt.Println("nice t1:", time.Time(t1))
  21. //fn(t1) // 编译错误
  22. fn(time.Time(t1))
  23. //t1 = fn2() // 编译错误
  24. t1 = YourTime(fn2())
  25. var t2 = MyTime{time.Now()}
  26. // t2 = t2.Add(time.Hour) // 编译错误
  27. t2.Time = t2.Add(time.Hour)
  28. fmt.Println("t2:", t2)
  29. //fn(t2) // 编译错误
  30. fn(t2.Time)
  31. //t2 = fn2() // 编译错误
  32. t2.Time = fn2()
  33. }

输出:

  1. ugly t1: {63393494400 0 0x1c9340}
  2. nice t1: 2009-11-11 00:00:00 +0000 UTC
  3. fn got: 2009-11-11 00:00:00 +0000 UTC
  4. t2: 2009-11-10 23:00:00 +0000 UTC
  5. fn got: 2009-11-10 23:00:00 +0000 UTC

你可以在Playground上运行这个示例。

英文:

Presumably you have type Mytime time.Time. If instead you embedded it:

  1. type MyTime struct {
  2. time.Time
  3. }

Then you could have:

  1. func (t MyTime) MarshalJSON() ([]byte, error) {
  2. whatever
  3. }

and still access all of time.Time's methods.
E.g. something like:

  1. t := MyType{time.Now()}
  2. 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).

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. type YourTime time.Time
  7. type MyTime struct{ time.Time }
  8. // Some random functions, perhaps in a third party package,
  9. // that deals with time.Time values.
  10. func fn(t time.Time) {
  11. fmt.Println("fn got:", t)
  12. }
  13. func fn2() time.Time {
  14. return time.Unix(14e8, 0)
  15. }
  16. func main() {
  17. var t1 = YourTime(time.Now())
  18. //t1 = t1.Add(time.Hour) // compiler error
  19. t1 = YourTime(time.Time(t1).Add(time.Hour))
  20. fmt.Println("ugly t1:", t1)
  21. fmt.Println("nice t1:", time.Time(t1))
  22. //fn(t1) // compiler error
  23. fn(time.Time(t1))
  24. //t1 = fn2() // compiler error
  25. t1 = YourTime(fn2())
  26. var t2 = MyTime{time.Now()}
  27. // t2 = t2.Add(time.Hour) // compiler error
  28. t2.Time = t2.Add(time.Hour)
  29. fmt.Println("t2:", t2)
  30. //fn(t2) // compiler error
  31. fn(t2.Time)
  32. //t2 = fn2() // compiler error
  33. t2.Time = fn2()
  34. }

<kbd>Playground</kbd>

Output:

  1. ugly t1: {63393494400 0 0x1c9340}
  2. nice t1: 2009-11-11 00:00:00 +0000 UTC
  3. fn got: 2009-11-11 00:00:00 +0000 UTC
  4. t2: 2009-11-10 23:00:00 +0000 UTC
  5. fn got: 2009-11-10 23:00:00 +0000 UTC

huangapple
  • 本文由 发表于 2015年4月2日 02:09:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/29397801.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定