[swift-evolution] Pitch: really_is and really_as operators

Xiaodi Wu xiaodi.wu at gmail.com
Thu Aug 25 21:36:31 CDT 2016


On Thu, Aug 25, 2016 at 17:08 Vladimir.S via swift-evolution <
swift-evolution at swift.org> wrote:

>  > 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?
>

There is no bug. Recall that "foo" is a string literal, which means that it
has no type of its own. Since NSString conforms to
ExpressibleByStringLiteral,"foo" is NSString == true because you are
testing if a value that's inferred to be of type NSString can be cast to
NSString. This does not have anything to do with bridging.

SE-0072 has to do with _implicit_ bridging from Objective-C to Swift (i.e.
NSString to String), and indeed you will find that implicit bridging in
that direction has been eliminated on a Mac:

```
import Foundation
let foo = "abc" as NSString
let bar: String = foo
// Error: NSString is not implicitly convertible to String [Fix-it: Insert
" as String"]
```

(Just got confused.. How should I cast NSString to String in Linux(or any)
> version of Swift?


On Darwin platforms, you perform an explicit conversion by writing `foo as
String` (where foo is your NSString instance).
On Linux, it appears you need to write `foo._bridgeToSwift()` for the
moment.

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
> >
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160825/ff8ac464/attachment.html>


More information about the swift-evolution mailing list