Scratch that, that won't work for the runtime type: isNumeric(0 as Any) == false // :(
On 10/4/2017 9:30 PM, Kevin Lundberg via swift-users wrote: > > Can you do something like this? > > func isNumber<T: Numeric>(_ value: T) -> Bool { return true } > > func isNumber<T>(_ value: T) -> Bool { return false } > > I don't recall whether or not swift will pick the right version of the > function here, or whether this can even compile (mac isnt open at the > moment), but if you can overload functions in this way then it might > be much nicer than checking for lots of concrete types. > > > On 10/1/2017 6:27 PM, V T via swift-users wrote: >> >> >>> On 1. Oct 2017, at 22:43, davel...@mac.com <mailto:davel...@mac.com> >>> wrote: >>> >>> >>> >>>> On Oct 1, 2017, at 2:32 PM, Glenn L. Austin <gl...@austinsoft.com >>>> <mailto:gl...@austinsoft.com>> wrote: >>>> >>>>> >>>>> On Oct 1, 2017, at 8:56 AM, Dave Reed via swift-users >>>>> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote: >>>>> >>>>> >>>>>> On Sep 21, 2017, at 3:58 PM, V T via swift-users >>>>>> <swift-users@swift.org <mailto: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 >>>> <http://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) >> #ifarch(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 >> > > > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users