今天在看源码的时候看到了一个数组,感觉很莫名其妙,代码如下:
代码
// daysBefore[m] counts the number of days in a non-leap year
// before month m begins. There is an entry for m=12, counting
// the number of days before January of next year (365).
var daysBefore = [...]int32{0,31,31 + 28,31 + 28 + 31,31 + 28 + 31 + 30,31 + 28 + 31 + 30 + 31,31 + 28 + 31 + 30 + 31 + 30,31 + 28 + 31 + 30 + 31 + 30 + 31,31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
}
解释
源码有注释,翻译过来是说:
这段代码定义了一个名为 daysBefore 的整数类型数组,用于存储每个月份开始之前的天数总和。数组的索引表示月份,从 1 开始,对应的数组元素值表示该月份开始之前的天数总和。
代码注释中提到 daysBefore[m] 表示一个非闰年中,在月份 m 开始之前的天数总数。数组最后一个项 daysBefore[12] 是表示明年一月之前的天数总数(365天)。对于非闰年来说,每个月的天数是固定的,所以可以直接计算出来并用来初始化数组。
例如,daysBefore[1] 表示一月份之前的天数总和,因为一月份之前没有任何天数,所以值为 0。daysBefore[2] 表示二月份之前的天数总和,其中的值为 31,表示一月份的总天数为 31。daysBefore[3] 表示三月份之前的天数总和,其中的值为 31 + 28,表示一月份和二月份的总天数为 59(因为二月份有 28 天)。以此类推,可以计算出每个月份之前的天数总和。
通过使用这个数组,可以很方便地计算某一日期是一年中的第几天。例如,要计算一月份的第 15 天是一年中的第几天,可以通过 daysBefore[1] + 15 来得到结果。同样地,可以通过 daysBefore[m] + d 来计算任意一天是一年中的第几天,其中 m 表示月份,d 表示日期。
疑惑
上面数组给出了闰年的解决方案,那平年呢?
首先我们需要可以判断是否是闰年,代码如下:
func isLeap(year int) bool {return year%4 == 0 && (year%100 != 0 || year%400 == 0)
}
所以计算某一天是某一年的第几天的代码如下:
// Add in days before this month.
d += daysBefore[month-1]
if isLeap(year) && month >= March {d++ // February 29
}// Add in days before today.
d += day - 1
总结:
非常推荐大家看一看优秀项目的源码,有些代码一看可能会不知所云,但思考过后很大可能会有不小收获。
阅读 Go 源码有很多好处,无论是对于学习,提高技术能力还是贡献于开源社区都有积极的影响。以下是一些看 Go 源码的好处:
-
学习编程语言和编程范式:透过阅读 Go 的源码可以深入理解 Go 语言的设计原理、语法和特性。这有助于加深对语言本身的理解,同时也有助于掌握 Go 的编程范式和最佳实践。
-
学习标准库和框架:通常,标准库是学习任何编程语言的关键部分。通过阅读 Go 的标准库源码,可以学习到如何正确使用标准库中的各种功能和API,并且可以看到标准库的实现细节和设计哲学。此外,阅读框架的源码可以帮助理解框架的工作原理和使用方式,从而提高开发效率。
-
学习开发范式和设计模式:Go 的源码是非常优雅和高效的,它使用了很多现代开发范式和设计模式。通过阅读源码,可以学习到如何应用这些范式和模式来解决实际问题,提高代码的可维护性、可扩展性和性能。
-
深入了解底层实现:Go 使用了一些底层原语和技术,如并发编程、垃圾回收和网络编程等。通过阅读源码,可以了解这些底层实现的原理和机制,以及它们是如何与语言特性和标准库相互配合的。
-
解决问题和调试:阅读源码是解决问题和调试的有力工具。当你遇到问题或者 Bug 时,阅读相关源码可以帮助你更好地理解问题的根本原因,并找到解决问题的方法。此外,对于想要贡献于开源社区的人来说,阅读源码能够提高对项目的理解,从而更好地为项目做出贡献。
总而言之,阅读 Go 源码可以提高我们的编程技能和问题解决能力,加深对 Go 语言和标准库的理解,并且有助于贡献于开源社区。不过,阅读源码需要有一定的基础知识和经验,因此建议先对 Go 语言有一定的了解和应用经验,同时结合实践和探索,逐步提高对源码的理解能力。