> On 1. Oct 2017, at 22:43, [email protected] wrote:
>
>
>
>> On Oct 1, 2017, at 2:32 PM, Glenn L. Austin <[email protected]> wrote:
>>
>>>
>>> On Oct 1, 2017, at 8:56 AM, Dave Reed via swift-users
>>> <[email protected]> wrote:
>>>
>>>
>>>> On Sep 21, 2017, at 3:58 PM, V T via swift-users <[email protected]>
>>>> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users