[swift-evolution] Pitch: really_is and really_as operators

Vladimir.S svabox at gmail.com
Thu Aug 25 17:08:10 CDT 2016


 > The behavior is due to the Objective-C bridge, which I don’t think exists
 > on the Linux version. On the Mac version, fooIsNSString will be true
 > because of the bridging magic that lets you convert between String and
 > NSString (and other equivalent Swift and Objective-C data types) using
 > “as”.

Well, if I understand correctly, exactly here we are trying to cast 
instance *typed* as `Any`, not as `String`. But it seems that this magic 
exists in Linux version too, but with little different behavior.
Just made some tests, got interested results:

Swift Ver. 3.0 (Aug 24, 2016)
Platform: Linux (x86_64)

import Foundation

let fooAsNSString = "foo" as NSString

print(type(of: fooAsNSString)) // NSString

let foo: Any = "Foo"
let fooAsString = "Foo"
let bar: Any = NSString(string: "Bar")

print(type(of: foo)) // String
print(type(of: bar)) // NSString

print(fooAsString is NSString) // false
print("foo" is NSString) // true

print(foo is NSString) // false
print(bar is NSString) // true


WARNINGS:
cast from 'String' to unrelated type 'NSString' always fails
print(fooAsString is NSString)

'is' test is always true
print("foo" is NSString)


Still, I believe that due to *SE-0072*
1) Linux version work more correctly and Mac's version should be fixed
2) There is a bug in Linux version, which produces
"foo" is NSString ==  true

Am I missing something?

(Just got confused.. How should I cast NSString to String in Linux(or any) 
version of Swift? Tried various variants like nsstring as! String and 
String(describing: nsstring) - got compilation/runtime error)

On 26.08.2016 0:31, Charles Srstka wrote:
>> On Aug 25, 2016, at 4:15 PM, Vladimir.S via swift-evolution
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>
>> > let fooIsNSString = foo is NSString           // true
>>
>> I don't understand. Why is so? On which version of Swift did you try this?
>>
>> IBM Swift Sandbox
>> Swift Ver. 3.0 (Aug 23, 2016)
>> Platform: Linux (x86_64)
>>
>> import Foundation
>>
>> let foo: Any = "Foo"
>> let bar: Any = NSString(string: "Bar")
>>
>> let fooIsString = foo is String
>> print(fooIsString) // true
>>
>> let fooIsNSString = foo is NSString
>> print(fooIsNSString) // false! as expected
>
> The behavior is due to the Objective-C bridge, which I don’t think exists
> on the Linux version. On the Mac version, fooIsNSString will be true
> because of the bridging magic that lets you convert between String and
> NSString (and other equivalent Swift and Objective-C data types) using
> “as”. Never mind that “foo as NSString” isn’t even fewer characters than
> “NSString(foo)”; somebody decided it was easier that way. And of course,
> “is”, “as?” and the rest of the family have to behave the same way for
> consistency. As a result, you can never be 100% sure what’s actually going
> to happen when you use “as?”, which is one of the reasons I dislike “as?”.
> SE-0083 attempted to remove this bridging magic from the dynamic casts and
> make them only truthfully report the type of the object or struct you were
> looking at, but it was deferred until “later in Swift 3”, and Swift 3 has
> progressed past the point where source-breaking changes are accepted, so
> that proposal is probably dead at this point.
>
> The source incompatibility that this bridging behavior can create between
> Swift on the Mac and on other platforms is actually a pretty good point in
> favor of SE-0083 that I wish we’d thought of before everything became
> locked down.
>
> Charles
>


More information about the swift-evolution mailing list