Search code examples
swiftgenericsintdouble

Do Int and Double share a common parent class in Swift


I'm wondering if there is an easier way to write these two initializers as a generic Initializer

public required init(_ value : Double) {
    super.init(value: value, unitType: unit)
}

public required init(_ value : Int) {
    let v = Double(value)
    super.init(value: v, unitType: unit)
}

Something like:

public init<T>(_value : T) {
    let v = Double(T)
    super.init(value: v, unitType: unit)
}

(which of course doesn't compile)

I've looked through the code of both Int and Double and am missing any real thing that ties them together.


Solution

  • Take a look at the Swift header:

    extension String : StringInterpolationConvertible {
        init(stringInterpolationSegment expr: String)
        init(stringInterpolationSegment expr: Character)
        init(stringInterpolationSegment expr: UnicodeScalar)
        init(stringInterpolationSegment expr: Bool)
        init(stringInterpolationSegment expr: Float32)
        init(stringInterpolationSegment expr: Float64)
        init(stringInterpolationSegment expr: UInt8)
        init(stringInterpolationSegment expr: Int8)
        init(stringInterpolationSegment expr: UInt16)
        init(stringInterpolationSegment expr: Int16)
        init(stringInterpolationSegment expr: UInt32)
        init(stringInterpolationSegment expr: Int32)
        init(stringInterpolationSegment expr: UInt64)
        init(stringInterpolationSegment expr: Int64)
        init(stringInterpolationSegment expr: UInt)
        init(stringInterpolationSegment expr: Int)
    }
    

    Similarly:

    func +(lhs: UInt8, rhs: UInt8) -> UInt8
    func +(lhs: Int8, rhs: Int8) -> Int8
    func +(lhs: UInt16, rhs: UInt16) -> UInt16
    func +(lhs: Int16, rhs: Int16) -> Int16
    func +(lhs: UInt32, rhs: UInt32) -> UInt32
    func +(lhs: Int32, rhs: Int32) -> Int32
    func +(lhs: UInt64, rhs: UInt64) -> UInt64
    func +(lhs: Int64, rhs: Int64) -> Int64
    func +(lhs: UInt, rhs: UInt) -> UInt
    func +(lhs: Int, rhs: Int) -> Int
    func +(lhs: Float, rhs: Float) -> Float
    func +(lhs: Double, rhs: Double) -> Double
    func +(lhs: Float80, rhs: Float80) -> Float80
    

    If it were possible to write one generic function for all those different numeric types, they would have done it, surely. So the answer to your question must be No.

    (And in any case they can hardly share a parent class, as they are not classes. They are structs.)

    Now, of course, if only Int and Double are in question, you could extend Int and Double to adopt a common protocol and make that protocol the expected type...