With only <T: Something>: how does `anNSNumber as? T` know what the actual numeric type is to cast?

So NSNumber has magic capability to allow it to cast to many supported numeric type.

But I don't understand how generic work to allow it to know what the numeric type is to cast when the generic constraint has no such information seemingly:

import Foundation
import SwiftUI

protocol Something { }
extension Double: Something { }

func convert<T: Something>(_ binding: Binding<T>) {
    // ??? How does it know T is what?
    if let value = NSNumber(value: 123) as? T {  // my example, how does it get Double here?
        binding.wrappedValue = value
    } else {
        fatalError("cannot convert type: \(T.self)")

    }
}

var d: Double = 0
let binding = Binding(get: { d }, set: { d = $0 })
convert(binding)
print("d = ", d)    // print: d = 123.0

Because:

  • d is a Double
  • binding is a Binding<Double>
  • convert takes a Binding<T>
  • you pass a Binding<Double> to convert
  • therefore, T is a Double in that example
1 Like

Okay, this is a better example showing where my mental blockage:

import Foundation
import SwiftUI

protocol Something { }
extension Double: Something { }

func convert<T: Something>(_ binding: Binding<T>) {
    print("convert, T is \(T.self)")
    // ??? How does it know T is what?
    if let value = NSNumber(value: 123) as? T {  // my example, how does it get Double here?
        binding.wrappedValue = value
    } else {
        fatalError("cannot convert type: \(T.self)")
    }
}

var abstractD: Something = 123.4
let abstractDBinding = Binding(get: { abstractD }, set: { abstractD = $0 })
convert(abstractDBinding)   // compile error: Protocol 'Something' as a type cannot conform to the protocol itself
print("abstractD = ", abstractD)

It's just strange to me it's this way, even though I've read protocol X does not conform to X.

I keep think convert<T: Something>, then T is only known to the compiler as Something. But it's really just "conformance" requirement. The real type is still used.