我有一个WorkDay结构,其中包含有关某人工作时间的数据,一个WorkWeek结构来保存一堆WorkDays,以及一个WorkMonth结构来保存一堆WorkWeek。我们的想法是让每个人返回在此期间工作的总时数。
type WorkDay struct {
StartTime time.Time
EndTime time.Time
}
type WorkWeek struct {
WorkDays []WorkDay
}
type WorkMonth struct {
WorkWeeks []WorkWeek
}
func (w WorkDay) HoursWorked() time.Duration {
// Find hours worked through simple subtraction.
}
func (w WorkWeek) HoursWorked() time.Duration {
var totalHours time.Duration
for _, day := range w.WorkDays {
totalHours += day.HoursWorked()
}
return totalHours
}
func (w WorkMonth) HoursWorked() time.Duration {
var totalHours time.Duration
for _, week := range w.WorkWeeks {
totalHours += week.HoursWorked()
}
return totalHours
}
这段代码工作得很好,但WorkWeek.HoursWorked()
和WorkMonth.HoursWorked()
中的重复确实让我感觉不舒服。我试着做以下事情,以为我很聪明:
func (w WorkWeek) HoursWorked() time.Duration {
return sumHoursWorked(w.WorkDays)
}
func (m WorkMonth) HoursWorked() time.Duration {
return sumHoursWorked(m.WorkWeeks)
}
type countable interface {
HoursWorked() time.Duration
}
func sumHoursWorked(timeFrames []countable) time.Duration {
var totalHours time.Duration
for _, frame := range timeFrames {
totalHours += frame.HoursWorked()
}
return totalHours
}
但是,正如here所述,尽管WorkDay
实现了countable
,但WorkDay
的切片不算作countable
的切片。
那么,是否有一些漂亮的,惯用的方式摆脱了我所遗漏的情况,或者我只是坚持复制?
答案 0 :(得分:4)
没有。要么有一片countables
,它会为您提供动态方法调度或一些编程(您的第一个解决方案)或重组您的类型。我不知道你的问题域,但几个星期组成的几个月似乎很奇怪,至少是月/周的东西。
答案 1 :(得分:2)
否,因为countables
的切片是另一种类型。
您可以定义自己的切片类型并为其附加Add方法。
func (w WorkWeek) HoursWorked() time.Duration {
return sumHoursWorked(w.WorkDays)
}
func (m WorkMonth) HoursWorked() time.Duration {
return sumHoursWorked(m.WorkWeeks)
}
type countable interface {
HoursWorked() time.Duration
}
type SliceCountable []countable
func (m *SliceCountable) Add( c countable ) {
*m = append(*m, c )
}
func (m SliceCountable) HoursWorked() time.Duration {
var totalHours time.Duration
for _, frame := range m {
totalHours += frame.HoursWorked()
}
return totalHours
}
func sumHoursWorked(timeFrames []countable) time.Duration {
var totalHours time.Duration
for _, frame := range timeFrames {
totalHours += frame.HoursWorked()
}
return totalHours
}