Go-解决接口切片问题的惯用方式

soz*_*ami 5 go

我有一个WorkDay结构,用于保存有关某人工作时间的数据,一个WorkWeek结构,用于存储一堆工作日,以及一个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
}
Run Code Online (Sandbox Code Playgroud)

这段代码可以正常工作,但是重复进行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
}
Run Code Online (Sandbox Code Playgroud)

然而,正如解释在这里,即使WorkDay器具countable,一片WorkDays不算作一片countable秒。

那么,是否有一些我不曾想到的巧妙而惯用的方法,还是我只是坚持复制呢?

Vol*_*ker 4

不。要么使用其中的一部分为countables您提供动态方法分派或一些编程(您的第一个解决方案),要么重新构造您的类型。我不知道你的问题领域,但是由数周组成的数月由数日组成的数月似乎很奇怪,至少是月/周的东西。