Func asOpt<T>(v:Any) -> Optional<T> { If let val = v as? T { Return val } Return nil } Regards LM (From mobile)
> On Jun 22, 2016, at 7:11 AM, Charlie Monroe via swift-evolution > <swift-evolution@swift.org> wrote: > > Unfortunately, this is not as easy, because automatic bridging won't be > applied: > > let myString: String? = "Hello" > let anyValue: Any = myString > > myString as? AnyObject // _NSContiguousString > anyValue as? AnyObject // nil, since String is struct > > let array: [String]? = ["Hello"] > let anyArray: Any = array > anyArray as? AnyObject // nil > anyArray as? [AnyObject] // nil > array as? AnyObject // ["Hello"] > > And this goes for strings, arrays, dictionaries and possibly other types. > Which means that you need to handle manually all of the bridging to ObjC > types, which has really grown in Swift 3, taking into account all the > Foundation types that are now structs. > > Should this then be considered compiler bug that bridging isn't taken into > account? > > Nevertheless, I'd still find it useful exposing the isOptional() function as > well as the asOptional which would allow a cast from Any to Optional<Any> > which is not possible at all at this moment since any such cast will pick up > the Optional first: > > let myString: String? = "Hello" > let anyValue: Any = myString > if let value = anyValue as? Any { > value.dynamicType // This is still Optional<String>, not naively just the > value of the optional > } > > > >> On Jun 21, 2016, at 8:18 PM, Joe Groff <jgr...@apple.com> wrote: >> >> 'as?' should already do this. If you have an Any that contains an >> Optional<T> and cast 'any as? T', you'll get the value inside the Optional >> if there is one, or the cast will fail if the optional is nil or the type >> doesn't match. >> >> -Joe >> >>> On Jun 20, 2016, at 11:00 PM, Charlie Monroe via swift-evolution >>> <swift-evolution@swift.org> wrote: >>> >>> I've recently written a CoreData editor on iOS which automatically >>> generates UI based on the model which is described using classes such as >>> PrimitiveProperty, etc. Since it automatically sets the value on the >>> entity, it needs to convert the value to AnyObject in order to pass it to >>> setValue(_:forKey:), so it needs to be able to detect whether the value is >>> Optional and in case it is, either transform the non-nil value to AnyObject >>> (String -> NSString, Array -> NSArray, ...). Which is currently really hard >>> to achieve: >>> >>> var obj: IndexPath? = IndexPath() >>> let anyValue: Any = obj >>> anyValue.dynamicType /// Optional<Foundation.IndexPath>.Type >>> >>> /// Using only anyValue, determine if it's Optional and retrieve its value >>> if >>> /// non-nil as AnyObject. >>> func isOptional(anyValue: Any) -> Bool { >>> // Error: Cannot downcast from 'Any' (aka 'protocol<>') to a more >>> // optional type 'Optional<_>' >>> return anyValue is Optional >>> return anyValue as? Optional != nil >>> ... >>> } >>> >>> Unless there are major reasons why it's not exposed, I'd propose >>> introducing a new function isOptional(anyValue: Any) -> Bool, which would >>> simply call Builtin.isOptional just like _isOptional does in Builtin.swift. >>> (which pretty much is just taking the current _isOptional, removing >>> underscore and marking it public). >>> >>> However, this still doesn't help with the issue of retrieving the value of >>> the Optional. You now know the value in `anyValue` is Optional, but there >>> is no good way to cast it to e.g. Optional<AnyObject>. Here we're getting >>> into a vicious cycle that Any can be an Optional which is Any. >>> >>> My second part of the proposal introduces another function: >>> >>> func asOptional<T>(anyValue: Any) -> Optional<T>? >>> >>> Which will: >>> - return nil if !isOptional(anyValue) >>> - return a non-nil value only if `anyValue` contains in fact an Optional of >>> type T. >>> >>> Usage: >>> >>> if let anyObjOptional: AnyObject? = asOptional(anyValue: anyValue) { >>> if let anyObj = anyObjOptional { >>> // anyObj is now the actual content of the optional. >>> } >>> } >>> >>> As a sidenote, this is my current workaround: >>> >>> private protocol _XUOptional { >>> var objectValue: AnyObject? { get } >>> } >>> >>> extension Optional: _XUOptional { >>> var objectValue: AnyObject? { >>> switch self { >>> case .None: >>> return nil >>> case .Some(_): >>> return self! as? AnyObject >>> } >>> } >>> } >>> >>> if let optional = anyValue as? _XUOptional { >>> let object = optional.objectValue >>> /// ... >>> } >>> >>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org >>> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution