- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我都读过 Optional Parameters?和 Golang pass nil as optional argument to a function?
仍然想知道我的案例是否更具体。
我得到的是:
type Periodical struct {
Interval *interval.Interval
StartsAt time.Time
EndsAt time.Time
}
表示具有开始日期且可能有也可能没有结束日期的周期性事件(周期性事件运行的时间不确定)。
eachYear := Periodical{
interval.Years(1),
StartsAt: time.Parse("2 Jan 2006", "1 Jan 1970")}
会抛出
periodical/periodical.go:31:39: cannot use nil as type time.Time in field value
据了解,- 我没有指定 EndsAt time.Time
。
但是我在那儿真正做什么呢?
我是否被迫有一个特殊的标志来像这样忽略 EndsAt
?
type Periodical struct {
Interval *interval.Interval
StartsAt time.Time
EndsAt time.Time
isIndefinite bool // This looks ugly already
}
然后如果我想要Yearly
/Anually
我会做类似的事情
eachYear := Periodical{
interval.Years(1),
time.Parse("2 Jan 2006", "1 Jan 1970"),
time.Parse("2 Jan 2006", "1 Jan 1970"),
isIndefinite: true}
尽管我可以在业务逻辑中考虑这个标志,但是这个设置为相同(或任何其他)日期的 EndsAt
看起来有点乏味。
我还在 periodical
包上定义了一个方法,它允许像这样有一个简写的定期事件:
func Monthly(s, e time.Time) Periodical {
return Periodical{StartsAt: s, EndsAt: e, Interval: interval.Months(1)}
}
我该怎么做才能省略 end
(第二个参数)?我是被迫为此使用单独的方法还是做一些看起来有点时髦且缺乏可读性的事情:
func Monthly(s time.Time, end ...time.Time) Periodical {
if len(end) == 1 {
return Periodical{
StartsAt: s,
EndsAt: end[0],
Interval: interval.Months(1),
isIndefinite: false}
} else if len(end) > 1 {
panic("Multiple end dates are not allowed, don't know what to do with those")
} else {
return Periodical{
StartsAt: s,
EndsAt: time.Now(),
Interval: interval.Months(1),
isIndefinite: true}
}
}
虽然它可以解决问题,但它看起来很难看,不是吗?我简洁的一行代码现在分散在几行代码中。
所以,这就是为什么我想知道,go 实现我想要做的事情的惯用方式是什么?
最佳答案
time.Time
是一个结构。它的zero value – 尽管是一个有效的时间值 – 就像从未使用过一样。您可以利用零值时间来指示丢失或未定义的时间值。甚至还有一个 Time.IsZero()
告诉您 time.Time
值是否为零值的方法。
请注意,零值时间不像其他一些语言那样是 1970 年 1 月 1 日,而是 1 年 1 月 1 日,正如您在 Go Playground 上看到的那样.这也记录在 time.Time
中:
The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC. As this time is unlikely to come up in practice, the IsZero method gives a simple way of detecting a time that has not been initialized explicitly.
此外,在创建 Periodical
值时,使用键控 composite literal ,并且您可以省略不想设置的字段,从而将它们保留为零值:
eachYear := Periodical{
Interval: interval.Years(1),
StartsAt: time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC),
}
请注意,您不能使用 time.Parse()
在这个复合文字中,它返回 2 个值(一个 time.Time
和一个 error
)。要么使用 time.Date()
如上例,或者先创建时间值(处理错误),直接使用时间值即可。
判断是否指定了 EndsAt
:
if eachYear.EndsAt.IsZero() {
fmt.Println("EndsAt is missing")
}
如果您需要将已设置的(非零)时间值归零,您可以使用 time.Time{}
复合文字:
eachYear.StartsAt = time.Time{}
另请注意,当编码(marshal)一个 time.Time
值时,即使它是零值(因为它是一个有效的时间值),即使您使用 omitempty
选项。在这些情况下,您必须使用 *time.Time
指针或编写自定义编码器。有关详细信息,请参阅 Golang JSON omitempty With time.Time Field .
关于go - 在结构中表示可选 time.Time 的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52216908/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!