> On 1. Oct 2017, at 22:43, davel...@mac.com wrote: > > > >> On Oct 1, 2017, at 2:32 PM, Glenn L. Austin <gl...@austinsoft.com> wrote: >> >>> >>> On Oct 1, 2017, at 8:56 AM, Dave Reed via swift-users >>> <swift-users@swift.org> wrote: >>> >>> >>>> On Sep 21, 2017, at 3:58 PM, V T via swift-users <swift-users@swift.org> >>>> wrote: >>>> >>>> Hi there! >>>> >>>> Is there a best way to check if a given type conforms to numeric protocol >>>> (Integer or FP) at runtime? >>>> >>>> func checkNumeric<T>(_ value: T) { >>>> /* return true if vaiue is Integer or FP */ >>>> /* this will not compile: */ >>>> if value is Numeric { >>>> >>>> } >>>> } >>>> >>>> Best regards! >>>> >>>> VT >>>> >>> >>> I think the way to do it is to try casting as the type, but you can't use >>> "as? Numeric" as you get: >>> >>> error: protocol 'Numeric' can only be used as a generic constraint because >>> it has Self or associated type requirements >>> >>> but you could check for each specific numeric type such as: >>> >>> func checkNumeric<T>(_ value: T) { >>> if (value as? Int != nil) || (value as? Float != nil) { >>> print("numeric") >>> } else { >>> print("not numeric") >>> } >>> } >>> >>> checkNumeric(3) >>> checkNumeric(3.0) >>> checkNumeric("3") >> >> You can also use the 'is' operator, as in 'value is Int || value is Float || >> value is Double' >> >> -- >> Glenn L. Austin, Computer Wizard, AustinSoft.com > > > Ah, I had forgotten "is" works in Swift > > Just be careful as: > > func checkNumeric<T>(_ value: T) { > if (value is Int) || (value is Float) { > print("numeric") > } else { > print("not numeric") > } > } >
Thanks all! My current implementation looks like this. A bit redundant, bat it works. My intention was to simplify that monster: func isNumber<T>(_ value: T) -> Bool { let valueMirror = Mirror(reflecting: value) #if arch(arm) || arch(arm64) if (valueMirror.subjectType == Int.self || valueMirror.subjectType == UInt.self || valueMirror.subjectType == Double.self || valueMirror.subjectType == Int8.self || valueMirror.subjectType == Int16.self || valueMirror.subjectType == Int32.self || valueMirror.subjectType == Int64.self || valueMirror.subjectType == UInt8.self || valueMirror.subjectType == UInt16.self || valueMirror.subjectType == UInt32.self || valueMirror.subjectType == UInt64.self || valueMirror.subjectType == Float.self || valueMirror.subjectType == Float32.self || valueMirror.subjectType == NSNumber.self || valueMirror.subjectType == NSDecimalNumber.self ) { return true } else { return false } #else if (valueMirror.subjectType == Int.self || valueMirror.subjectType == UInt.self || valueMirror.subjectType == Double.self || valueMirror.subjectType == Int8.self || valueMirror.subjectType == Int16.self || valueMirror.subjectType == Int32.self || valueMirror.subjectType == Int64.self || valueMirror.subjectType == UInt8.self || valueMirror.subjectType == UInt16.self || valueMirror.subjectType == UInt32.self || valueMirror.subjectType == UInt64.self || valueMirror.subjectType == Float.self || valueMirror.subjectType == Float32.self || valueMirror.subjectType == Float80.self || valueMirror.subjectType == NSNumber.self || valueMirror.subjectType == NSDecimalNumber.self ) { return true } else { return false } #endif } > checkNumeric(3) > checkNumeric(3.0) > checkNumeric("3") > > outputs: > > numeric > not numeric > not numeric > > Since the literal 3.0 is a Double so you'd have to catch every floating point > type (including CGFloat, I suspect etc.) vs. just trying to cast to a Float > (although I guess casting to a Float could have unexpected results also if > someone made an extension that allows a type to be cast as a Float). > > Dave > >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users