можно ли считать, что Свифт НЕ делает это?
Вы можете предполагать все, что захотите, но независимо от языка программирования, ваш абсолютный лучший вариант - просто попробовать его и узнать. Если бы вы вставили образец кода на игровое поле или в любую среду с поддержкой Swift или просто попытались запустить его через командную строку, вы бы быстро обнаружили, что это просто не работает.
Ваш вопрос несколько сбивает с толку, но я думаю, что могу рассмотреть все или, по крайней мере, большинство ваших вопросов.
x = 10
var y = x + 10
var x
Предполагая, что нет другого кода для вашего оригинального образца, он просто не компилируется. У всех трех линий есть проблема.
Первые две строки жалуются на использование неразрешенных идентифицированных «х». На английском языке это означает, что Swift не может понять, какую переменную вы говорите. Переменные в Swift должны быть объявлены до их использования, поэтому объявление в строке три не помогает следующим двум строкам.
Третья строка жалуется, что не может определить, какой тип x
должен быть. Msgstr "Типовая аннотация отсутствует в шаблоне". В некоторых случаях Swift может определить, какой тип нашей переменной должен быть. Например, с var x = 10
, Swift может определить, что тип x
должен быть Int
. Если мы хотим чего-то еще, мы должны указать. Но если мы не назначаем значение в декларации, Swift не имеет ни малейшего представления, и нужно сказать: var x: Int?
Что о случае, когда x
существует в другой области?
Ну, Swift допускает переменное затенение. То есть переменная, объявленная в одной области видимости, скрывает переменную, объявленную в другой области видимости.
Так, например:
class Foo {
let x = 10
func foo(value: Int) -> Int {
let a = value * self.x
let x = 10
return a * x
}
}
Теперь мы можем использовать некоторыеx
, прежде чем мы объявили локально областью действия x
, но это разные переменные. Кроме того, возможно, самое главное, обратите внимание на self.
, добавленный к x
. Это необходимо. Без этого Swift откажется компилировать этот код и будет жаловаться: «Использовать локальную переменную« x »перед ее объявлением».
Однако в рамках функций классов это не единственное место, где мы можем теневые переменные. Мы также можем сделать это в пределах if
блоков (среди других мест), в которых вещи могут стать немного более запутанными. Рассмотрим это:
class Foo {
let x = 10
func foo(value: Int) -> Int {
print(x)
if x > 3 {
let x = 2
print(x)
}
return x
}
}
Здесь мы использовали x
дважды, прежде чем объявить его. И нам не нужно было использовать self.
, и он не жалуется и компилируется отлично. Но важно отметить, что внеif
блока (включая x > 3
условные) x
мы ссылаемся переменная экземпляра, но внутри if
блока, мы создали новую переменные с именем x
которого Shadows переменную экземпляра. Мы также можем создать такой же вид затенения, используя конструкции if let
и if var
(но не guard let
).
В результате вызова этой функции будет что значение 10
печатается, мы входим в if
блок, значение 2
печатается, то мы выходим из if
блока и значение 10
возвращается.
Теперь давайте через var
в смесь здесь. Во-первых, если вы еще не знаете, вы должны начать с чтения this, который объясняет разницу между let
и var
(одна постоянная, другая - нет).
Давайте объединим let
против var
с прицелом и переменной теневой системой, чтобы увидеть, как это влияет на вещи.
class Foo {
let x = 10
func foo(value: Int) -> Int {
print(x)
if x > 3 {
var x = 2
while x < 10 {
print(x)
x += 3
}
return x
}
return x
}
}
Хорошо, так это то же самое, как и раньше, но с немного более сложным битом в пределах if
блока.
Здесь наша переменная локально обозначена как var
, а наша переменная экземпляра остается постоянной let
. Мы не можем изменить переменную экземпляра, но мы можем изменить локальную переменную. И мы делаем это на каждой итерации цикла while
.
Но важно, чтобы эта переменная была совершенно другой переменной из переменной экземпляра. Это может также иметь совершенно другое имя (и на практике, в основном это всегда должно быть иметь другое название). Таким образом, изменение нашей локальной переменной x
ничего не меняет нашу более широкую переменную экземпляра x
. Это разные переменные, которые находятся в разных местах памяти.И как только переменная объявлена как let
или var
, эта переменная не может быть изменена на другую.
Ваш вопрос немного сбивает с толку, но, если предположить, что в другом месте нет другого объявления 'x', это не будет компилироваться в Swift. http://i.imgur.com/rrjHvS8.png – nhgrif
Я нашел это полезным: [В чем разница между 'let' и' var' в swift?] (http://stackoverflow.com/questions/24002092/what-is-the-difference-between-let-and-var-in-swift) –
@MartinR Я думаю, что OP ссылается на поведение JavaScript и спрашивает, одинаково ли поведение в Swift - одно ключевое различие заключается в том, что 'var' (в JS) переводит переменные в ближайшую область действия; 'let' не делает, и вместо этого блокируется область. В этом смысле основное различие между ними - это область, в которой они доступны. Тем не менее, вопрос основан на неправильном предположении: это не потому, что JavaScript скомпилирован или интерпретирован, потому что у 'var' была странная спецификация , –