> On Jun 22, 2016, at 9:12 AM, Charlie Monroe via swift-evolution > <swift-evolution@swift.org> wrote: > > Please consider the following code: > > let myString: String? = "Hello" > let anyValue: Any = myString > let obj: AnyObject? = anyValue as? AnyObject // nil, since it's > Optional<String>, String being struct, > // no implicit bridge to AnyObject. > (myString as AnyObject will > // create _NSContiguousString). > > if let optionalAny: AnyObject? = anyValue as? AnyObject? { // Error - can't > downcast from Any > // ... > } > > if let optionalAny: AnyObject? = anyValue as? AnyObject { // nil > // ... > } > > if let optionalAny: AnyObject? = asOpt(anyValue) { // Optional<AnyObject> > if let value = optionalAny { // value is _NSContiguousString > value.dynamicType > } > } > > This behavior is IMHO incosistent at best. Should this be considered correct > behavior or a compiler bug?
A bug. -Joe >> On Jun 22, 2016, at 5:59 PM, L.Mihalkovic <laurent.mihalko...@gmail.com> >> wrote: >> >> >> >> On Jun 22, 2016, at 5:51 PM, John McCall <rjmcc...@apple.com> wrote: >> >>> >>>> On Jun 22, 2016, at 12:15 AM, L. Mihalkovic via swift-evolution >>>> <swift-evolution@swift.org> wrote: >>>> >>>> Func asOpt<T>(v:Any) -> Optional<T> { >>>> If let val = v as? T { >>>> Return val >>>> } >>>> Return nil >>>> } >>>> Regards >>>> LM >>>> (From mobile) >>> >>> This is just: >>> return v as? T >> >> Had more code where i took it from... I thk it is one of these simple thgs >> that u never forget but may not be immediate to thk abt. Maybe worth adding >> to doc comment for Optional<> (forgive if is there already) >> >>> >>> John. >>> >>>> >>>> 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 >>> > > _______________________________________________ > 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