Question 1: in guard let self = self else { return }
, first self
and second self
are same, why it can be compiled successfully? Because normal let self = self
will be compiled with errors.
Question 2: Even I found guard let self else { return }
in some projects, why it can be compiled successfully?
2
Answers
A few links for your reference:
SE-0079 discusses the use of
if let self = self {…}
pattern:That proposal replaces the legacy pattern of …
… with something that avoids the confusion of introducing a separate variable name, reducing it to:
The shortening of this syntax is contemplated in SE-0345, which says:
The pattern works for
self
, too, so thus the example in my first point is reduced to:FWIW, SE-0365, in its discussion of “implicit self”, shows lots of examples of the the
guard
pattern:By writing
let self = self
you declare a variableself
and give it a value ofself
(i.e., a reference to the instance of the object that the line is called inside).Swift allows variable shadowing, so it’s legal to create a local variable
self
that shadows the identifierself
from the outer scope.There’s one caveat, though:
self
is also a special word in Swift and can’t be used as a variable name (the compiler emits the error "Keyword ‘self’ cannot be used as an identifier here")… unless you apply an escaping technique: let `self` = self.On the other hand,
guard
doesn’t require this kind of escaping. I suppose that since the idiomguard let self = self
is so common, language developers decided to make an exception for it to avoid some boilerplate code.In later versions of the language, they also introduced a shorthand syntax for unwrapping optional values:
guard let self
. In fact you can use it with any optional variable to unwrap it:guard let anyOptional
.As for why
guard let self else { return }
cannot be compiled in some places, it’s impossible to say without more details, but I have two assumptions:self
itself might be unavailable in the context (i.e., the code is written outside of an instance of an object, e.g., in the global scope).