[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