挑战2:更高级的前进()
以下是您在本章前面看到的Simpledate结构的Naïve的写作方式:

   let months = ["January", "February", "March",
             "April", "May", "June",
             "July", "August", "September",
             "October", "November", "December"]

struct SimpleDate {
 var month: String
 var day: Int

 mutating func advance() {
   day += 1
 }
}

var date = SimpleDate(month: "December", day: 31)
date.advance()
date.month // December; should be January!
date.day // 32; should be 1!

当函数从一个月结束到下一个月的开始时会发生什么?
重写晋级()以从12月31日到1月1日推广。

let months = ["January", "February", "March",
              "April", "May", "June",
              "July", "August", "September",
              "October", "November", "December"]

struct SimpleDate {
    var month: String
    var day: Int {
        didSet {
            switch month {
            case "January":
                if day > 31 {
                    month = "February"
                    day = 1
                }
                
            case "February":
                if day > 28{ // dont have year to calculate leap
                    month = "March"
                    day = 1
                }
                
            case "March":
                if day > 31{
                    month = "April"
                    day = 1
                }
                
            case "April":
                if day > 30{
                    month = "May"
                    day = 1
                }
                
            case "May":
                if day > 31{
                    month = "June"
                    day = 1
                }
                
            case "June":
                if day > 30{
                    month = "July"
                    day = 1
                }
                
            case "July":
                if day > 31{
                    month = "August"
                    day = 1
                }
                
            case "August":
                if day > 31{
                    month = "September"
                    day = 1
                    
                }
                
            case "September":
                if day > 30{
                    month = "October"
                    day = 1
                }
                
            case "October":
                if day > 31{
                    month = "November"
                    day = 1
                }
                
            case "November":
                if day > 30{
                    month = "December"
                    day = 1
                }
                
            case "December":
                if day > 31{
                    month = "January"
                    day = 1
                }
            default:
                return
            }
        }
    }
    
    mutating func advance() {
        day += 1
    }
    
}

即使问题得到解决,但我不喜欢我解决它的方式。有条件有一些方式凝聚的方法吗?

谢谢

感谢分享。

让我刚开始脱掉哪个是明显的,你永远不应该在生产代码中使用手滚动日期类,除非你“知道你在做什么”。如果你认为你这样做,你可能没有。无论如何,我不。看 //yourcalendricalfallacyis.com

如果您在项目中使用日期和时间,您可能需要退房: //github.com/davedelong/time

如果您只想使用Foundation,我会这样做:

import Foundation
let someDate = Date()
let updated = Calendar(identifier: .gregorian).date(byAdding: DateComponents(day: 1), to: someDate)

现在,回到你的问题,

您可能会使您的月份排列如下:

[("January", 31, "February"), ("February", 28, "March"), 
  ("March", 31, "April"), ... ]

Then you could mechanistically use months[index].0 for the current month, months[index].1 for how many days, and months[index].2. The idea is to separate the code and the data. It obviously doesn’t work for leap years in this case. There are more advanced techniques you could use to get around that but then you might want to go back to using Date! :微笑:

这一主题在166天后自动关闭。不再允许新的回复。