> On Jun 22, 2016, at 9:12 AM, Charlie Monroe <char...@charliemonroe.net> 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?

The inability to cast from Any to an optional is a bug.

John.

> 
>> On Jun 22, 2016, at 5:59 PM, L. Mihalkovic <laurent.mihalko...@gmail.com 
>> <mailto:laurent.mihalko...@gmail.com>> wrote:
>> 
>> 
>> 
>> On Jun 22, 2016, at 5:51 PM, John McCall <rjmcc...@apple.com 
>> <mailto:rjmcc...@apple.com>> wrote:
>> 
>>> 
>>>> On Jun 22, 2016, at 12:15 AM, L. Mihalkovic via swift-evolution 
>>>> <swift-evolution@swift.org <mailto: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 <mailto: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 
>>>>>> <mailto: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 <mailto:evolut...@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 <mailto:swift-evolution@swift.org>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
> 

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to