> 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
<[email protected] <mailto:[email protected]>> 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

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to