You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on May 1, 2026. It is now read-only.
Extending Int and Double with properties second, seconds, minute, etc. seems like a rather bad idea. There's two problems with this:
Anyone using your code in a project with other 3rd-party code that wants to do something similar will have a compile-time naming collision, making it impossible to use either one.
It's weakly-typed. You're still taking NSTimeInterval as your actual time type, and all it takes is for someone to accidentally leave off the .minutes and they'll get the wrong time. This isn't a huge issue, as NSTimeInterval is used everywhere to mean seconds and people are used to it, but we can still do better.
The better approach is to use an actual Duration type that requires the user to type the unit as part of the constructor. With the ruby-like approach you can just say NSTimer.after(1) { ... } but with a proper strong type there's no way to do this. I'd suggest something like
/// A type that represents a given duration.
publicstructDuration:Comparable,Hashable,Printable,DebugPrintable{
/// The time interval of the `Duration`, in seconds.
letseconds:NSTimeInterval
/// The time interval of the `Duration`, in minutes.
varminutes:NSTimeInterval{return seconds /60}
/// The time interval of the `Duration`, in hours.
varhours:NSTimeInterval{return seconds /3600}
/// The time interval of the `Duration`, in milliseconds.
/// Sub-millisecond values are truncated.
varmilliseconds:Int64{returnInt64(seconds *1_000)}
/// The time interval of the `Duration`, in microseconds.
/// Sub-microsecond values are truncated.
varmicroseconds:Int64{returnInt64(seconds *1_000_000)}
/// The time interval of the `Duration`, in nanoseconds.
varnanoseconds:Int64{returnInt64(seconds *1_000_000_000)}
/// Construct a `Duration` for a given number of seconds.
publicinit(seconds:NSTimeInterval){self.seconds = seconds
}
/// Construct a `Duration` for a given number of minutes.
publicinit(minutes:NSTimeInterval){self.init(seconds: minutes *60)}
/// Construct a `Duration` for a given number of hours.
publicinit(hours:NSTimeInterval){self.init(seconds: hours *3600)}
/// Construct a `Duration` for a given number of milliseconds.
// Use Int64 because milliseconds are generally not floating-point
// values
publicinit(milliseconds:Int64){self.init(seconds:NSTimeInterval(milliseconds)/1_000)}
/// Construct a `Duration` for a given number of microseconds.
publicinit(microseconds:Int64){self.init(seconds:NSTimeInterval(microseconds)/1_000_000)}
/// Constructs a `Duration` for a given number of nanoseconds.
// How much tolerance does a timer actually support?
publicinit(nanoseconds:Int64){self.init(seconds:NSTimeInterval(nanoseconds)/1_000_000_000)}publicvardescription:String{
// TODO: Display human-readable string with multiple units
returntoString(seconds)}publicvardebugDescription:String{return"Duration(\(seconds))"}publicvarhashValue:Int{return seconds.hashValue
}}publicfunc+(lhs:Duration, rhs:Duration)->Duration{returnDuration(seconds: lhs.seconds + rhs.seconds)}publicfunc-(lhs:Duration, rhs:Duration)->Duration{returnDuration(seconds: lhs.seconds - rhs.seconds)}
// NB: Don't implement multiplication/division, that doesn't make any sense for
// durations. As such, we don't conform to IntegerArithmeticType either.
publicfunc<(lhs:Duration, rhs:Duration)->Bool{return lhs.seconds < rhs.seconds
}publicfunc==(lhs:Duration, rhs:Duration)->Bool{return lhs.seconds == rhs.seconds
}
This way you can then say NSTimer.after(Duration(seconds: 1)) { ... }. You could also experiment with replacing all those initializers with static functions instead (e.g. static func seconds(seconds: NSTimeInterval)) so that way you can say NSTimer.after(.seconds(1)) { ... }.
Extending
IntandDoublewith propertiessecond,seconds,minute, etc. seems like a rather bad idea. There's two problems with this:NSTimeIntervalas your actual time type, and all it takes is for someone to accidentally leave off the.minutesand they'll get the wrong time. This isn't a huge issue, asNSTimeIntervalis used everywhere to mean seconds and people are used to it, but we can still do better.The better approach is to use an actual
Durationtype that requires the user to type the unit as part of the constructor. With the ruby-like approach you can just sayNSTimer.after(1) { ... }but with a proper strong type there's no way to do this. I'd suggest something likeThis way you can then say
NSTimer.after(Duration(seconds: 1)) { ... }. You could also experiment with replacing all those initializers with static functions instead (e.g.static func seconds(seconds: NSTimeInterval)) so that way you can sayNSTimer.after(.seconds(1)) { ... }.