(This probably needs a better title...)
I would like to have a set of accessors I can use in code to quickly express time durations. E.g:
42.seconds
3.14.minutes
0.5.hours
13.days
This post illustrates that you can't just do it with a simple new protocol, extension, and forcing IntegerType
and FloatingPointType
to adopt that. So I thought I'd just go the more redundant route and just extend IntegerType
directly (and then repeat the code for FloatingPointType
).
extension IntegerType {
var seconds:NSTimeInterval {
return NSTimeInterval(self)
}
}
The error generated is confusing:
Playground execution failed: /var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/9325/playground131.swift:31:10: error: cannot invoke initializer for type 'NSTimeInterval' with an argument list of type '(Self)'
return NSTimeInterval(self)
^
/var/folders/2k/6y8rslzn1m95gjpg534j7v8jzr03tz/T/./lldb/9325/playground131.swift:31:10: note: overloads for 'NSTimeInterval' exist with these partially matching parameter lists: (Double), (UInt8), (Int8), (UInt16), (Int16), (UInt32), (Int32), (UInt64), (Int64), (UInt), (Int), (Float), (Float80), (String), (CGFloat), (NSNumber)
return NSTimeInterval(self)
What confuses me is that it seems to say that I can't do an NSTimeInterval() initializer with (Self), but everything Self represents is listed in the next line where it shows all of the possible initializers of NSTimeInterval. What am I missing here?
Aside: I would love it if there were a well written tutorial on Swift's type system and doing these kinds of things. The intermediate/advanced stuff is just not well covered in Apple's sparse Swift documentation
Update/Clarification:
What I want is to be able to evaluate any of the above expressions:
42.seconds --> 42
3.14.minutes --> 188.4
0.5.hours --> 1800
13.days --> 1123200
Furthermore, I want the return type of these to be NSTimeInterval (type alias for Double), such that:
42.seconds is NSTimeInterval --> true
3.14.minutes is NSTimeInterval --> true
0.5.hours is NSTimeInterval --> true
13.days is NSTimeInterval --> true
I know that I can achieve this by simply extending Double
and Int
as such:
extension Int {
var seconds:NSTimeInterval {
return NSTimeInterval(self)
}
var minutes:NSTimeInterval {
return NSTimeInterval(self * 60)
}
var hours:NSTimeInterval {
return NSTimeInterval(self * 3600)
}
var days:NSTimeInterval {
return NSTimeInterval(self * 3600 * 24)
}
}
extension Double {
var seconds:NSTimeInterval {
return NSTimeInterval(self)
}
var minutes:NSTimeInterval {
return NSTimeInterval(self * 60)
}
var hours:NSTimeInterval {
return NSTimeInterval(self * 3600)
}
var days:NSTimeInterval {
return NSTimeInterval(self * 3600 * 24)
}
}
But I would also like the following expression to work:
let foo:Uint = 4242
foo.minutes --> 254520
foo.minutes is NSTimeInterval --> true
This won't work though because I have only extended Int
, not UInt
. I could redundantly extend Uint
, and then UInt16
, and then Int16
, etc....
I wanted to generalize the extension of Int
to IntegerType
as shown in the original listing, so that I could just gain the conversions generally for all integer types. And then do the same for FloatingPointType
rather than specifically Double
. However, that produces the original error. I want to know why I can't extend IntegerType as generally shown. Are there other IntegerType
adopters other than the ones shown in the list, that make it so the NSTimeInterval() initializer does not resolve?