Is "x? .Y" in Swift the same as "x?" and then ".y"?

I understand that in Swift if I define

var opt:String? = "Optional"


I will get an error if I try



because it opt

has a type String?

that has no method isEmpty

. And I thought I realized that



does not raise an error because it opt?

unpacks (any not nil

) opt

, which results in String

which method has isEmpty

. But



by its own results in String?

, not a String


Is ?.

another operator from ?

followed by .





and get an impressive error.


source to share

2 answers

But the opponent? on its own results in String? not a string.

Yes. According to Swift language reference, Expressions, Postfix Expressions, Optional-Expression chaining :

Postfix itself? the operator simply returns the value of its argument as optional.

Thus, placing ?

itself at the end of an optional is a complete no-op. It has no effect.

There is?. another operator? and then.?

Yes. More specifically, it ?

has the optional chaining effect when used in any "postfix expression", including when ()

(function call), .

(member access) and []

(index) follow .



Yes opt?.isEmpty

different from String?

. It's called optional chaining . From a quick programming guide:

You specify an optional string by putting a question mark (?) After the optional value on which you want to call a property, method, or index, if the optional parameter is nonzero. This is very similar to placing an exclamation mark (!) After an optional value to force the expansion of its value. The main difference is that the extra chaining fails gracefully when the optional parameter is zero, whereas the forced unwrapping triggers a runtime error when the option is zero.

This creates an optional as you think var opt: String?


 opt?.isEmpty //it will not crash if opt is nil 


matches the exception

opt!.isEmpty //it will crash if opt is nil 


if opt!

- nil

, than will not crash at runtime. The optional chaining is used to call long sequences of optional chaining without calling. Each additional chain returns an optional ie opt? returns the optional expands it, and if nil than not calling isEmpty else, calling isEmpty and reutns value. Also



When you write the instruction above, it is optional (optional) and it cannot be unpacked due to curly braces. This error displays

$T2?? does not have a member named `isEmpty`


to expand it



it will return false

Edit: More ...

   var o1 = opt?
   var o2 = ((opt?)?)


does nothing on its own, it just assigns a value o1

, o2

ie String ?. to expand opt

and o1

, o2

they are both optional and need one statement !

to expand it.

Also, please don't understand between String?

and opt?

they are both different, when? used after some type in a declaration that it makes optional, and when ?

used after a variable opt

it is used to unwrap in an optional chaining and return an optional return value

Additional materials:

try this to clarify

(((opt?)?)!).isEmpty     //it will unwrap with single !
((((opt?)?)!)?).isEmpty   //compiler will show suggestion to remove ?


the below statement makes optional optional

   var opt:String??? = "Optional"


to deploy





always returns optional, but if opt

defined as String! it implicit optional

and opt?

will return optional(explicit)

. But if it opt

does opt?

n't necessarily do anything

From the Quick Programming Guide

In other words:

If the type you are trying to retrieve is not optional, it will become optional because of the optional chaining.
If the type you are trying to retrieve is already optional, it will not become more optional because of the chaining.



If you try to retrieve an Int value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.
Similarly, if you try to retrieve an Int? value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.




All Articles