2015-12-20 2 views
1

Я изучаю Swift, и поскольку в Linux теперь есть компилятор, я его установил и протестировал некоторые программы. И есть одна вещь, которую я не понимаю. Почему этот надуманный пример дает ошибку во время компиляции?Переменная область в блоке

var x = 86; 

if x <= 32 { 
    ++x; 
    print(x); 
} else if x >= 86 { 
    x = 2 * x; 
    print(x); 
    var x = false; 
    if !x { 
     print(x); 
    } 
} else { 
    --x; 
    print(x); 
} 
print(x); 

ошибка:

15.swift:7:5: error: use of local variable 'x' before its declaration 
    x = 2 * x; 
    ^
15.swift:9:9: note: 'x' declared here 
    var x = false; 
     ^
15.swift:7:13: error: use of local variable 'x' before its declaration 
    x = 2 * x; 
      ^
15.swift:9:9: note: 'x' declared here 
    var x = false; 
     ^
15.swift:8:11: error: use of local variable 'x' before its declaration 
    print(x); 
     ^
15.swift:9:9: note: 'x' declared here 
    var x = false; 
     ^

Почему это так? Я имею в виду, это не магия, соответствующий пример в C++ работает как можно себе представить:

#include <iostream> 
using namespace std; 
int main() { 
    int x = 86; 
    if (x <= 32) { 
     ++x; 
     cout << x << endl; 
    } else if (x >= 86) { 
     x = x * 2; 
     bool x = false; 
     if (!x) { 
      cout << x << endl; 
     } 
    } else { 
     --x; 
     cout << x << endl; 
    } 
    cout << x << endl; 

    return 0; 
} 

Так что мой вопрос: я просто найти ошибку в Swift компилятора или это просто, что Свифт использует некоторую менее интуитивную область видимости семантику? Если да, где я могу прочитать об этом? Кажется, так странно.

+0

Я думаю, что C++ пример страдает от серьезных проблем читаемости, что может привести к трудно найти ошибки, потому что 'x' относится к совершенно разные вещи в одном контексте. Я не знаю, когда это хорошая идея использовать этот шаблон. Предупреждения Swift намного лучше, ИМХО. – Rob

+0

Но это не только предупреждения. Swift отказывается выполнять мой код. И мне интересно, все в порядке. Я знаю, что пример C++ не является хорошим кодом. Но дело не в этом. Дело в том, что я думаю, что я должен иметь возможность переопределять переменную в другой области - в блоке. Это работает на C++, и я уверен, что это более интуитивно понятно для многих программистов. – xan

+0

Это странно, потому что он компилируется на Xcode. Может быть, ошибка Linux? – sunshinejr

ответ

0

это должно работать на вас. (А) вы не можете переопределить переменную в части текущей области, (б) Bool и Int типа не являются взаимозаменяемыми в Swift

var x = 86; 

if x <= 32 { 
    ++x; 
    print(x) 
} else if x >= 86 { 
    x = 2 * x 
    print(x) 
    var xb = false 
    if !xb { 
     print(x) 
    } 
} else { 
    --x 
    print(x) 
} 
print(x) 

это основа вашей проблемы

var x = 1 
var x = true // error: invalid redeclaration of 'x' 

@xan не является неустойчивым. вы не можете переопределить переменную. вы можете объявить новый для всей семантической единицы.

var x = 1 
for i in 1...3 { 
    var x = 10 
    print(i,x) // 1 10, 2 10, 3 10 
} 
print(x) // 1 

, чтобы лучше понять Swift поведение и различия в C, посмотрите на эту

var x = 1 
repeat { 
    var x = 10 // 
    print(x--) // 10 10 
    print(++x) // 10 10 
    x++ 
    print(x) // 11 11 
} while x-- > 0 
print(x) // -1 
+0

Это не совсем так. Вы можете объявлять переменные с тем же именем и другим типом локально. Докажите это, удалив строку 'x = 2 * x' и переместите строку' var x = false' над первой линией 'print' как в пределах' else'. – vadian

+0

@vadian, точно. И я знаю, что этот код может быть исправлен, но дело не в этом. Точка - это семантика, которая, по-видимому, очень неустойчива. Как отмечалось, иногда мы можем переопределить переменную в блоке, а иногда и нет. Меня смущает, что мой пример не компилируется. – xan

+0

@vadian, пожалуйста, сначала посмотрите, что парень пытается сделать, прежде чем жаловаться. и правильно проверить, что я написал ... (a) – user3441734

Смежные вопросы