1

Is it possible to convert any integer value in to a Double using generics? I'd like to make this function a bit more convenient so I can jam any number in here without having to convert the hour and minute arguments I pass in to Doubles. Mostly just to get my head around generics more than anything else.

Looking in to Double's documentation the closest thing I can find is Double(exactly: T) but it gives me an optional value while I can't find any protocols that will both support the + and * operators and allow me to convert to a Double. I'd like to do this without creating my own protocol if it's possible.

This doesn't work but illustrates what I'm trying to do:

///Returns a Date object for today set to a given time on a 24 hour clock
private func today<T: SignedInteger>(hour: T = 0, minute: T = 0, second: T = 0) -> Date {
    let secondsPastMidnight: Double = Double(exactly: hour)! * 60 * 60 + Double(exactly: minute)! * 60 + Double(exactly: second)!
    return Date().startOfDay.addingTimeInterval(secondsPastMidnight)
}

Calling the above like so:

let superEarlyMeeting = Meeting(UUID: "0", startTime: today(), endTime: today(hour: SharedGlobals.Calendar.WORK_HOURS_START))

Give an error for: Generic parameter 'T' could not be inferred

Declan McKenna
  • 4,321
  • 6
  • 54
  • 72

1 Answers1

1

Double(exactly:) fails if the integer is not exactly representable as a 64-bit IEEE-754 floating point number, i.e. for integers greater or equal to 9,007,199,254,740,993 in magnitude, that should not be a problem when working with hours, minutes, and seconds. (Actually it does not fail at all, which is a bug).

Alternatively you can convert via the largest signed integer type, e.g.

Double(Int64(hour))

which returns the closest representable floating point number as a non-optional.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • When I call the function in my question I get a `Generic parameter T could not be inferred` error. (I've updated the question to show the call). I'm not sure why this appears as my return value isn't generic. – Declan McKenna Jan 02 '18 at 21:40
  • 1
    If you call `today()` with no arguments then the compiler cannot infer the type `T`, that has nothing to do with the conversion from `T` to `Double` inside the function. You have to pass at least one argument, e.g. `today(second: 0)` – Martin R Jan 02 '18 at 21:41
  • Ah that make's sense, I'll make hours non-optional. Thanks – Declan McKenna Jan 02 '18 at 21:49
  • Looks like `Double(exactly:)` gives a fatal error whenever I use it. Your alternative works fine. – Declan McKenna Jan 03 '18 at 10:18