Optional binding with non-optional expression


(Martin R) #1

This following code fails to compile (which is correct, as far as I can judge that):

   if let x = 5 { }
   // error: initializer for conditional binding must have Optional type, not 'Int'

But why is does it compile (with a warning) if an explicit type annotation is added?

   if let y: Int = 5 { }
   // warning: non-optional expression of type 'Int' used in a check for optionals

Tested with Xcode 8.3.2 and both the build-in Swift 3.1 toolchain and the Swift 4.0 snapshot from May 25, 2017.

I am just curious and would like to understand if there is fundamental difference between those statements.

Regards, Martin


(Zhao Xin) #2

I think it did an unnecessary implicitly casting. For example,

let y = Int(exactly: 5)

print(type(of:y)) // Optional<Int>

You code equals to

if let y:Int = Int(exactly: 5) { }

However, I don't know why it did that. Maybe because of type inferring?

Zhaoxin

···

On Fri, Jun 2, 2017 at 8:40 PM, Martin R via swift-users < swift-users@swift.org> wrote:

This following code fails to compile (which is correct, as far as I can
judge that):

   if let x = 5 { }
   // error: initializer for conditional binding must have Optional type,
not 'Int'

But why is does it compile (with a warning) if an explicit type annotation
is added?

   if let y: Int = 5 { }
   // warning: non-optional expression of type 'Int' used in a check for
optionals

Tested with Xcode 8.3.2 and both the build-in Swift 3.1 toolchain and the
Swift 4.0 snapshot from May 25, 2017.

I am just curious and would like to understand if there is fundamental
difference between those statements.

Regards, Martin

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


(Martin R) #3

I don’t think that explains it (or perhaps I did not understand your response correctly).

Here is the same issue with a custom type (which does not have a failable initializer):

   struct A { }

   if let a = A() { }
   // error: initializer for conditional binding must have Optional type, not 'A'

   if let a: A = A() { }
   // warning: non-optional expression of type 'A' used in a check for optionals

···

Am 02.06.2017 um 15:49 schrieb Zhao Xin <owenzx@gmail.com>:

I think it did an unnecessary implicitly casting. For example,

let y = Int(exactly: 5)
print(type(of:y)) // Optional<Int>

You code equals to

if let y:Int = Int(exactly: 5) { }

However, I don't know why it did that. Maybe because of type inferring?

Zhaoxin

On Fri, Jun 2, 2017 at 8:40 PM, Martin R via swift-users <swift-users@swift.org> wrote:
This following code fails to compile (which is correct, as far as I can judge that):

   if let x = 5 { }
   // error: initializer for conditional binding must have Optional type, not 'Int'

But why is does it compile (with a warning) if an explicit type annotation is added?

   if let y: Int = 5 { }
   // warning: non-optional expression of type 'Int' used in a check for optionals

Tested with Xcode 8.3.2 and both the build-in Swift 3.1 toolchain and the Swift 4.0 snapshot from May 25, 2017.

I am just curious and would like to understand if there is fundamental difference between those statements.

Regards, Martin

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


(Zhao Xin) #4

Then I knew it.

if let a: A = A() { // this is a warning as it treats like always true

    print("something") // this line always runs

}

For

if let a = A() { // show an error as the compiler thinks you are missing
something.

}

For me, the first example, explicitly given the type of `a`, so it is a
warning. The second example, is one step farther than the first one. And it
is shown as an error.

Each one of them is correct by itself. But putting together, there is a
self-contradictory feeling.

Zhao Xin

···

On Sun, Jun 4, 2017 at 6:00 PM, Martin R <martinr448@gmail.com> wrote:

I don’t think that explains it (or perhaps I did not understand your
response correctly).

Here is the same issue with a custom type (which does not have a failable
initializer):

   struct A { }

   if let a = A() { }
   // error: initializer for conditional binding must have Optional type,
not 'A'

   if let a: A = A() { }
   // warning: non-optional expression of type 'A' used in a check for
optionals

> Am 02.06.2017 um 15:49 schrieb Zhao Xin <owenzx@gmail.com>:
>
> I think it did an unnecessary implicitly casting. For example,
>
> let y = Int(exactly: 5)
> print(type(of:y)) // Optional<Int>
>
> You code equals to
>
> if let y:Int = Int(exactly: 5) { }
>
> However, I don't know why it did that. Maybe because of type inferring?
>
> Zhaoxin
>
> On Fri, Jun 2, 2017 at 8:40 PM, Martin R via swift-users < > swift-users@swift.org> wrote:
> This following code fails to compile (which is correct, as far as I can
judge that):
>
> if let x = 5 { }
> // error: initializer for conditional binding must have Optional
type, not 'Int'
>
> But why is does it compile (with a warning) if an explicit type
annotation is added?
>
> if let y: Int = 5 { }
> // warning: non-optional expression of type 'Int' used in a check for
optionals
>
> Tested with Xcode 8.3.2 and both the build-in Swift 3.1 toolchain and
the Swift 4.0 snapshot from May 25, 2017.
>
> I am just curious and would like to understand if there is fundamental
difference between those statements.
>
> Regards, Martin
>
>
>
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>