2016-02-02 6 views
-2

Как известно, JavaScript «Поднимет» переменные в верхней части файла или области. Но из моего понимания, используя let такого же, как var только let ограничиваются объемом он определен в.Быстрый подъем?

Будучи компилируемым языком вместо интерпретируемым, мы можем предположить, Swift НЕ делает это?

Например:

x = 10 

var y = x + 10 

var x 
+0

Ваш вопрос немного сбивает с толку, но, если предположить, что в другом месте нет другого объявления 'x', это не будет компилироваться в Swift. http://i.imgur.com/rrjHvS8.png – nhgrif

+1

Я нашел это полезным: [В чем разница между 'let' и' var' в swift?] (http://stackoverflow.com/questions/24002092/what-is-the-difference-between-let-and-var-in-swift) –

+1

@MartinR Я думаю, что OP ссылается на поведение JavaScript и спрашивает, одинаково ли поведение в Swift - одно ключевое различие заключается в том, что 'var' (в JS) переводит переменные в ближайшую область действия; 'let' не делает, и вместо этого блокируется область. В этом смысле основное различие между ними - это область, в которой они доступны. Тем не менее, вопрос основан на неправильном предположении: это не потому, что JavaScript скомпилирован или интерпретирован, потому что у 'var' была странная спецификация , –

ответ

7

можно ли считать, что Свифт НЕ делает это?

Вы можете предполагать все, что захотите, но независимо от языка программирования, ваш абсолютный лучший вариант - просто попробовать его и узнать. Если бы вы вставили образец кода на игровое поле или в любую среду с поддержкой 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, эта переменная не может быть изменена на другую.

2

'пусть' и 'вар' не имеют разницы в объеме.

Глобальные переменные - это переменные, которые определяются за пределами любых функций, методов, замыканий или типов объектов . Локальными переменными являются переменные , определенные в функции, методе или закрытии. контекст.